140 likes | 308 Views
Paradyn as a Strict Dyninst Client. James Waskiewicz. Motivation. Low-level instrumentation code base has two classes of users Paradynd Dyninst API users This has led to… Internal code fragmentation (ifdefs, etc)
E N D
Paradyn as a Strict Dyninst Client James Waskiewicz
Motivation • Low-level instrumentation code base has two classes of users • Paradynd • Dyninst API users • This has led to… • Internal code fragmentation (ifdefs, etc) • Un-necessarily complex internal code (doing reliable instrumentation is hard enough!) • Testability issues • Extra complexity in the development process • A cleaner, more manageable code base ! • We’ve been talking about this for years • Its time to actually do something
Goals • Dyninst does instrumentation • Paradyn uses instrumentation to do performance analysis • Currently does instrumentation using the same low-level code that Dyninst API uses • Need to: • Migrate paradyn-specific code from the low level code base to paradynd • “Rephrase” code in paradynd to use the publicly exported Dyninst interface • Augment DyninstAPI with functionality that is currently paradyn-specific
Basic Process: low-level -> paradynd • Isolate paradyn-specific concepts • Included/excluded functions • “Resources” • traceLink – a pipe to libparadynRT • Find ways to migrate these to paradynd • using existing APIs if possible (and reasonable) • Add APIs to Dyninst as necessary to support paradyn’s existing needs • Added APIs should be generally useful for other DyninstAPI users
Basic Process 2: paradynd using dyninst • Exhaustively track down every single reference to the low level code • This is a rather large problem • Luckily, much low-level code in paradynd has an existing analogue on the BPatch layer • Unfortunately, there are some gaping holes in DyninstAPI that need to be filled in • Eg: Instrumenting threaded targets • Divide and Conquer • By “subsystem” in paradynd – eg: MDL • By low level class (eg: remove all references to class “AstNode”)
Divide and Conquer: MDL • MDL (Metric Definition Language) is responsible for converting high-level instrumentation requests into low-level, nuts-and-bolts instrumentation code. • Eg. “Measure the amount of time the process spends in the execution of function foo(), in module bar.c” • Typically requires navigation of source objects (modules, functions, variables, etc). • Instrumentation code represented as AstNodes • MDL modified to use BPatch-layer symbols • Eg. Use BPatch_module instead of pdmodule • MDL modified to use BPatch-layer code generation • Eg. Use BPatch_snippet instead of AstNode • Currently uses BPatch_snippet infrastructure, but code insertion still relies on AstNode
Divide and Conquer, con’t. • Migrated concept of included/excluded functions/modules from Dyninst to paradynd • Provides a way for paradyn to restrict which functions/modules are available for performance analysis • No internal representation will be created for an “excluded” function/module • A paradyn-specific concept • Modified paradynd init to use • loadLibrary() to load libparadynRT • BPatch_snippets instead of instMappings
Some Added APIs • When to add something? • Concept used by paradyn, but not yet exported via dyninstAPI • Must be “generally useful” to tool builders (other than paradyn) • BPatch_regExpr • New type of BPatch_snippet representing the contents of a specific register • Exports AstNode::DataReg
Some Added APIs, con’t • Thread Event Callbacks • registerThreadEventCallback(), allows users to provide callbacks for thread events • Eg. Thread creation, thread termination, context-switch • Callbacks may be specified on either mutator-side, or in the mutatee as BPatch_functions • Prototypes: • bool registerThreadEventCallback( BPatch_asyncEventType t, BPatchThreadEventCallback cb) • bool registerThreadEventCallback( BPatch_asyncEventType t, BPatch_function *cb)
Some Added APIs, con’t • Dynamic Call Callbacks • A dynamic call site is a call site where the called function cannot be determined statically (eg. functions called by function pointer) • registerDynamicCallCallback() • allows users to provide a callback to report dynamic call events directly to the mutator • bool registerDynamicCallCallback( BPatchDynamicCallSiteCallback cb) • BPatch_point::monitorCalls() • Provide mutatee-side callback for dynamic call sites • bool monitorCalls(BPatch_function *cb) • <cb> must be provided in a user-loaded shared library • <cb> must adhere to a prescribed prototype
More on New Event Callbacks • Events are asynchronous • Mutatee is NOT stopped • Reported via socket connection with mutatee • DyninstAPI is now threaded • A BPatch-layer asynchronous event handling subsystem runs on a pthread • A global mutex controls access to ALL internal Dyninst data structures • Future locking refinement anticipated, depending upon performance considerations • Modular Implementation: BPatch_eventLock • Locking implemented via a base class to most exported BPatch-layer classes • Does NOT require tools using dyninst to be thread safe
Event Callbacks, con’t • The current plan: Three (or more) threads in Dyninst • Primary mutator thread (tool) • Synchronous process event handling thread (wait for a mutatee signal) • Asynchronous event handling thread (detect events without stopping the mutatee) • Why? • Solves problem of multiple event sources • Should greatly simplify existing (synchronous) process event handling code
As We Speak… • Fully migrate class “resource” from low-level code to paradyn • Used by paradyn for source navigation • Another Paradyn-specific concept • Continued work on internal threading • More platforms: currently only power-AIX, x86-linux, and sparc-solaris • Current implementation “transitional” until three-thread system can be completed • Stability questions will persist until then • In place, but still in progress. • Full multithread support • Thanks to Matt Legendre
Coming up… • More of the same • Iterative elimination of low level code from paradyn/paradynd • Dovetail with MT support • Crucial to Paradyn-on-top-of-Dyninst • Active discussion under way