1 / 15

DynC : High Level Instrumentation With Dyninst

DynC : High Level Instrumentation With Dyninst. Emily Jacobson. Motivation: Dyninst vs. DynC. DynC API. int main( int argc , char * argv []) { BPatch_process * proc = bpatch.processCreate (“ myMutatee ”); BPatch_image *image = proc -> getImage ();

tevy
Download Presentation

DynC : High Level Instrumentation With Dyninst

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DynC: High Level Instrumentation With Dyninst Emily Jacobson DynC and DynC API

  2. Motivation: Dyninst vs. DynC DynC API intmain(intargc, char *argv[]) { BPatch_process * proc = bpatch.processCreate(“myMutatee”); BPatch_image *image = proc->getImage(); bpatch.registerExitCallback( readMaxArg ); proc->malloc(*image->findType("int"), “mallocCounter”); FILE *dynCEntryFile = fopen( “entryDynC.txt”, “r”); FILE *dynCExitFile= fopen( “exitDynC.txt”, “r”); std::vector<BPatch_function *> allFunctions; image->getProcedures(allFunctions); for (FuncVector::iterator iter = funcs.begin(); iter!= funcs.end(); ++iter) { PointVector*entryPts= (*iter)->findPoint(Bpatch_Entry); PointVector*exitPts= (*iter)->findPoint(BPatch_locExit); BPatch_snippet*entrySnippet= DynC_API::createSnippet(dynCEntryFile, (iter*)->entryPts[0]); BPatch_snippet*exitSnippet = DynC_API::createSnippet(dynCExitFile, (iter*)->exitPts[0]); proc->insertSnippet(*entrySnippet, *entryPts); proc->insertSnippet(*exitSnippet, *exitPts); } proc->continueExecution(); while (!proc->isTerminated()) bpatch.waitForStatusChange(); return 0; } Dyninst API int main(intargc, char *argv[]) { BPatch_process * proc = bpatch.processCreate(“myMutatee”); BPatch_image *image = proc->getImage(); bpatch.registerExitCallback( readMaxArg ); //Create level variable BPatch_variableExpr*globalLevel = process->malloc(image->findType("int")); // Entry Snippet BPatch_variableExpr*globalVar = image->findVariable("a_global_var"); BPatch_paramExpr*paramVar = new BPatch_paramExpr(0); BPatch_localVar*localVar = NULL; // Cannot be built independantly BPatch_retExpr*ret = new BPatch_retExpr(); BPatch_variableExpr*entryCounter = NULL; BPatch_variableExpr*exitCounter = NULL; std::vector<BPatch_function *> *funcs; BPatch_function*printfFunc = image->findFunction("printf", funcs); std::vector<BPatch_function *> allFunctions; image->getProcedures(allFunctions); for (FuncVector::iterator iter = funcs.begin(); iter!= funcs.end(); ++iter) { // Assign our local variable entryCounter= process->malloc(image->findType("int")); local = (*iter)->findLocalVar("a_local_var"); // Allocate a counter entryCounter= proc->malloc(image->findType("int")); exitCounter= proc->malloc(image->findType("int")); std::vector<BPatch_snippet *> args; args.push_back(BPatch_constExpr("(level %d) Entering %s[at %p] for the %d time: parameter = %s, local = %d, global = %d.\n")); args.push_back(globalLevel); char fname[512]; args.push_back((iter*)->getName(fName, 512)); args.push_back(new BPatch_originalAddressExpr()); args.push_back(entryCounter); args.push_back(paramVar); args.push_back(localVar); args.push_back(globalVar); //build printf BPatch_funcCallExpr*printfExprEntry = new BPatch_funcCallExpr(printfFunc, args); args= std::vector(); args.push_back(BPatch_constExpr("(level %d) Exiting %s: returning = %d, global = %d.\n")); args.push_back(globalLevel); char fname[512]; args.push_back((iter*)->getName(fName, 512)); args.push_back(BPatch_retExpr()); args.push_back(globalVar); BPatch_funcCallExpr*printfExprExit = new BPatch_funcCallExpr(exitFunc, args); // Now that we have the snippets, get points and instrument std::vector<BPatch_points *> *entryPs = (*iter)->findPoint(BPatch_locEntry); std::vector<BPatch_points *> *exitPs = (*iter)->findPoint(BPatch_locExit); proc->insertSnippet(*entry, *entryPs); proc->insertSnippet(*exit, *exitPs); } } DynC and DynC API

  3. Evolution of DynC Mutator Interactive Shell User Code Dyner C CodeGen Dyninst API DynC API DynC and DynC API

  4. Runtime Compilation Dyninst API DynC API int i = 0 inf`foo += 5 DynC Snippet if(inf`foo > i++){ inf`printf(“Done”); } DynC and DynC API

  5. Runtime Compilation Dyninst API DynC API int i = 0 inf`foo += 5 DynC Snippet if(inf`foo > i++){ inf`printf(“Done”); } DynC and DynC API

  6. Runtime Compilation Dyninst API DynC API DynC Snippet DynC and DynC API

  7. Runtime Compilation Dyninst API DynC API DynC Snippet incl %eax mov %eax,.. addis r1,.. stw r1,... BPatch Snippet DynC and DynC API

  8. DynC API BPatch_Snippet *createSnippet(<snippet>, <location>) <snippet> char * std::string FILE * <location> BPatch_Point BPatch_AddressSpace DynC and DynC API

  9. Tracing Execution with DynC • Print out: • Globals: tick_count • Locals: local_iter • Parameters and return values • Function names, addresses, and execution counts • Call stack depth ... (level 1) Entering funcFoo[0x010], count 1: param= “sim”, str_length= 3, tick_count = 3. (level 2) Entering funcBar[0x080], count 3: param = “emul”, str_length = 4, tick_count = 42. (level 2) Exiting funcBar: returning 320, tick_count = 80. (level 1) Exiting funcFoo: returning 1000, tick_count = 110. ... DynC and DynC API

  10. Naming Functions and Variables Mutatee • DynC uses naming rather than lookup • Domains specify naming scope • Global domain • Local domain • Parameter domain • Inferior domain • Dyninst domain // Global variables inttick_count = 0; // Functions intfoo(char *str) { intstr_length = strlen(str); int hash = 0; for (inti = 0; i < str_length; ++i) { bar(...); } return hash; } int bar(char *str) { ... } // Library functions intprintf(char *format, ...); DynC and DynC API

  11. Example: DynC Entry Instrumentation • Access information about the instrumented point • Function name • Original address • Effective address of a memory operation • Thread ID or index • Target of indirect control flow // global_level is a variable we allocated char *funcName = dyninst`function_name; void *funcAddr = dyninst`original_address; inf`printf(“(level %d) Entering %s[%p]”, global`global_level++, funcName, funcAddrs); static intentryCounter = 0; inf`printf(“count = %d”, entryCounter++); char *funcParam = param`0; inf`printf(“param = \”%s\””, funcParam); intlocalVar = local`str_length; inf`printf(“local_iter = %d”, str_length); intglobalVar = global`tick_count; inf`printf(“tick_count = %d\n”, globalVar); DynC and DynC API

  12. Example: DynC Entry Instrumentation • Declare and access variables // global_level is a variable we allocated char *funcName = dyninst`function_name; void *funcAddr = dyninst`original_address; inf`printf(“(level %d) Entering %s[%p]”, global`global_level++, funcName, funcAddrs); static intentryCounter = 0; inf`printf(“count = %d”, entryCounter++); char *funcParam = param`0; inf`printf(“param = \”%s\””, funcParam); intlocalVar = local`str_length; inf`printf(“local_iter = %d”, str_length); intglobalVar = global`tick_count; inf`printf(“tick_count = %d\n”, globalVar); DynC and DynC API

  13. Example: DynC Entry Instrumentation • Access parameters • By number or name // global_level is a variable we allocated char *funcName = dyninst`function_name; void *funcAddr = dyninst`original_address; inf`printf(“(level %d) Entering %s[%p]”, global`global_level++, funcName, funcAddrs); static intentryCounter = 0; inf`printf(“count = %d”, entryCounter++); char *funcParam = param`0; inf`printf(“param = \”%s\””, funcParam); intlocalVar = local`str_length; inf`printf(“local_iter = %d”, str_length); intglobalVar = global`tick_count; inf`printf(“tick_count = %d\n”, globalVar); DynC and DynC API

  14. Example: DynC Entry Instrumentation • Access local and global variables // global_level is a variable we allocated char *funcName = dyninst`function_name; void *funcAddr = dyninst`original_address; inf`printf(“(level %d) Entering %s[%p]”, global`global_level++, funcName, funcAddrs); static intentryCounter = 0; inf`printf(“count = %d”, entryCounter++); char *funcParam = param`0; inf`printf(“param = \”%s\””, funcParam); intlocalVar = local`str_length; inf`printf(“local_iter = %d”, str_length); intglobalVar = global`tick_count; inf`printf(“tick_count = %d\n”, globalVar); DynC and DynC API

  15. Summary and Status • C-style instrumentation interface • Domains identify functions and variables • Beta in Dyninst 7 • Interface feedback welcomed • Demo: 2:00 – 3:00, Room 1170 • Tutorial: Tomorrow 9:00 – 12:00, Room 1260 DynC and DynC API

More Related