Dyninst
Scalable Tools Workshop
Granlibakken Resort Lake Tahoe, California
Dyninst Scalable Tools Workshop Granlibakken Resort Lake Tahoe, - - PowerPoint PPT Presentation
Dyninst Scalable Tools Workshop Granlibakken Resort Lake Tahoe, California Dyninst Scalable Tools Workshop A Brief Introduction to Dyninst Dyninst: a tool for static and dynamic binary instrumentation and modification 2 Dyninst Scalable
Scalable Tools Workshop
Granlibakken Resort Lake Tahoe, California
Dyninst Scalable Tools Workshop
2
Dyninst Scalable Tools Workshop
Parse API
A Dyninst Component
Dataflow API
A Dyninst Component
Proc Control API
A Dyninst Component
Patch API
A Dyninst Component
Stack Walker API
A Dyninst Component
Symtab API
A Dyninst Component
Instruction API
A Dyninst Component
Codegen
A Dyninst Component
DynC
A Dyninst Component
Binary Binary
Process
3
Dyninst Scalable Tools Workshop
4
Dyninst Scalable Tools Workshop
Dyninst /usr http:
ElfUtils TBB Boost
Boost ElfUtils TBB
Test suite
/usr http:
ElfUtils TBB Boost
Boost ElfUtils TBB
5
Dyninst Scalable Tools Workshop
⚫ All CMake variable names are now uniform across all dependencies ⚫ Many new variables have been exposed for finer control of the build ⚫ Export all CMake variables into cache ⚫ applications use them through CMake’s load_cache
Caveat: rpath doesn’t work fully (yet)
6
Dyninst Scalable Tools Workshop
Dyninst is one of three applications testing the CI workflow for ECP New build script for turnkey building and testing of Dyninst git clone dyninst git clone testsuite perl build.pl
github.com/dyninst/testsuite
7
Dyninst Scalable Tools Workshop
What effect does this have on you?
Users: None
Developers: Github pull requests will be manually run through the new build script before acceptance
Future:
8
Dyninst Scalable Tools Workshop
○
Uses function level parallelism in ParseAPI
○
Speedup relative to 1 thread is ~2-4x
○
GNU memory allocator
○
symbol table construction
○
parse frame initialization
○
parse finalization
9
Dyninst Scalable Tools Workshop
○
Optimized parallel ParseAPI
○
New parallel SymtabAPI
○
Parallel symbol table construction
○
Parallel parsing frame initialization
○
Parallel finalization
○
Remove redundant calculation
○
Scalable allocator from TBB
10
Dyninst Scalable Tools Workshop
Performance compared to 10.1 version
Speedup
11
Dyninst Scalable Tools Workshop
Code analysis: complete Dynamic instrumentation: complete Binary rewriting:
○ Dynamically-linked code: complete ○ Statically-linked code: in progress
12
Dyninst Scalable Tools Workshop
13
Dyninst Scalable Tools Workshop
Process
Function Add(…) You have a process (or a binary) that contains a function and you want to collect information such as:
How would you do this? You could modify the source code to include your instrumentation, recompile, and rerun
14
Dyninst Scalable Tools Workshop
Process
Function Add(…) You have a process (or a binary) that contains a function and you want to collect information such as:
How would you do this? You could modify the source code to include your instrumentation, recompile, and rerun Drawbacks: Maintain instrumentation w/ application source, source code may not be available (i.e. closed source), etc
15
Dyninst Scalable Tools Workshop
Process
Function Add(…) You have a process (or a binary) that contains a function and you want to collect information such as:
How would you do this? You could modify the source code to include your instrumentation, recompile, and rerun Drawbacks: Maintain instrumentation w/ application source, source code may not be available (i.e. closed source), etc. You could avoid these problems by using binary instrumentation.
16
Dyninst Scalable Tools Workshop
Show an example of how to use Dyninst to insert entry/exit instrumentation into a function.
○ Function call to a tracing
library at entry/exit.
00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
Function Entry/Exit Instrumentation
17
Dyninst Scalable Tools Workshop addrSpace = bpatch.processCreate(…);
the function you want to trace
00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
Function Entry/Exit Instrumentation
18
Dyninst Scalable Tools Workshop addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit)
00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace->loadLibrary(“libtrace.so”); Function Entry/Exit Instrumentation
19
Dyninst Scalable Tools Workshop addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit)
00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace->loadLibrary(“libtrace.so”); libtrace.so
XXX <Trace>: …: push %rbp … …: retq
Function Entry/Exit Instrumentation
20
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”); Function Entry/Exit Instrumentation
21
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
trace = addrSpace->findFunction(“Trace”); Function Entry/Exit Instrumentation
22
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
trace = addrSpace->findFunction(“Trace”);
entry = add->findPoint(BPatch_locEntry); exit = add->findPoint(BPatch_locExit); Function Entry/Exit Instrumentation
23
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
trace = addrSpace->findFunction(“Trace”);
entry = add->findPoint(BPatch_locEntry); exit = add->findPoint(BPatch_locExit);
BPatch_funcCallExpr traceExpr(trace,…) Function Entry/Exit Instrumentation
24
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
trace = addrSpace->findFunction(“Trace”);
entry = add->findPoint(BPatch_locEntry); exit = add->findPoint(BPatch_locExit);
BPatch_funcCallExpr traceExpr(trace,…)
addrSpace->insertSnippet(traceExpr,entry) Function Entry/Exit Instrumentation
25
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: call Trace 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp call Trace 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
trace = addrSpace->findFunction(“Trace”);
entry = add->findPoint(BPatch_locEntry); exit = add->findPoint(BPatch_locExit);
BPatch_funcCallExpr traceExpr(trace,…)
addrSpace->insertSnippet(traceExpr,entry) addrSpace->insertSnippet(traceExpr,exit) Function Entry/Exit Instrumentation
26
Dyninst Scalable Tools Workshop
Only minor modifications are needed to extend this example to:
Instrumentation
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: call Trace 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp call Trace 60d: retq
Function Entry/Exit Instrumentation
27
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: call Trace 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp call Trace 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
trace = addrSpace->findFunction(“Trace”);
entry = add->findPoint(BPatch_locEntry); exit = add->findPoint(BPatch_locExit);
BPatch_funcCallExpr traceExpr(trace,…)
addrSpace->insertSnippet(traceExpr,entry) addrSpace->insertSnippet(traceExpr,exit) Function Entry/Exit Instrumentation
28
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
Basic Block Instrumentation libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: call Trace 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp call Trace 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
BPatch_funcCallExpr traceExpr(trace,…)
addrSpace->insertSnippet(traceExpr,entry) addrSpace->insertSnippet(traceExpr,exit)
add->getCFG()->getAllBasicBlocks(blocks) for(auto block : blocks) entry.push_back(block->findEntryPoint()) exit.push_back(block->findExitPoint())
trace = addrSpace->findFunction(“Trace”);
29
Dyninst Scalable Tools Workshop add = addrSpace->findFunction(“add”);
Load/Store Operation Instrumentation libtrace.so
XXX <Trace>: …: push %rbp … …: retq 00000000000005fa <add>: call Trace 5fa: push %rbp 5fb: mov %rsp,%rbp 5fe: mov %edi,-0x4(%rbp) 601: mov %esi,-0x8(%rbp) 604: mov
607: mov
60a: add %edx,%eax 60c: pop %rbp call Trace 60d: retq
addrSpace = bpatch.processCreate(…);
the function you want to trace
want to call at entry/exit) addrSpace->loadLibrary(“libtrace.so”);
BPatch_funcCallExpr traceExpr(trace,…)
addrSpace->insertSnippet(traceExpr,lsp)
std::set<BPatch_opCode> axs; axs.insert(BPatch_opLoad); axs.insert(BPatch_opStore); lsp = add->findPoint(axs)
trace = addrSpace->findFunction(“Trace”);
30
Dyninst Scalable Tools Workshop
Walk through the stack frames that lead to the current program counter address Example Use Cases:
crashes
measurement
void main() { int a; foo(0); … } void foo(int b) { int c; bar(); … } void bar() { int d; while(1); } We will be doing third-party stack walk (attach to the process of the code example)
31
Dyninst Scalable Tools Workshop
void main() { int a; foo(0); … } void foo(int b) { int c; bar(); … } void bar() { int d; while(1); }
main's frame object: FP RA SP a foo's frame object: FP RA SP bar's frame object: FP RA SP Stack memory FP Registers SP PC b main's RA main's FP c foo's RA foo's FP d
We use binary analysis, DWARF frame information, signal context information, and analyze Dyninst instrumentation to extract frames
32
Dyninst Scalable Tools Workshop
void main() { int a; foo(0); … } void foo(int b) { int c; bar(); … } void bar() { int d; while(1); }
main's frame object: FP RA SP foo's frame object: FP RA SP bar's frame object: FP RA SP walker = Walker::newWalker(pid);
vector<Frame> frames; Walker->walkStack(frames);
// function name of frame i frame[i].getName(s); // stack pointer value of frame i frame[i].getSP() // frame pointer value of frame i frame[i].getFP() // return address of frame i frame[i].getRA()
33
Dyninst Scalable Tools Workshop
Determine which code in a binary have been executed through a test run.
34
Dyninst Scalable Tools Workshop
Determine which code in a binary have been executed through a test run. What for? To know how well their tests actually test their code. To know whether they have enough testing in place.
35
Dyninst Scalable Tools Workshop
Determine which code in a binary have been executed through a test run. What for? To know how well their tests actually test their code. To know whether they have enough testing in place. Dyninst can be used to perform code coverage at function level or basic block level.
36
Dyninst Scalable Tools Workshop
Code coverage
functions = addrSpace->getProcedures() XXX <add>: XXX: push %rbp ... XXX: retq YYY <sub>: YYY: push %rbp ... YYY: retq ZZZ <printf>: ZZZ: push %rbp ... ZZZ: retq
Dyninst Scalable Tools Workshop
Code coverage
vectorFlag = addrSpace()->malloc(n) functions = addrSpace->getProcedures() XXX <add>: XXX: push %rbp ... XXX: retq YYY <sub>: YYY: push %rbp ... YYY: retq ZZZ <printf>: ZZZ: push %rbp ... ZZZ: retq
Dyninst Scalable Tools Workshop
Code coverage
for (auto i : functions) BPatch_arithExpr assign(BPatch_assign, vectorFlag[i], BPatch_constExpr(1)); BPatch_breakPointExpr bp; addrSpace->insertSnippet(assign,point) addrSpace->insertSnippet(bp,point) vectorFlag = addrSpace()->malloc(n) functions = addrSpace->getProcedures()
XXX <add>: XXX: inc vectorFlag[0] XXX: break XXX: push %rbp ... XXX: retq YYY <sub>: YYY: inc vectorFlag[1] YYY: break YYY: push %rbp ... YYY: retq ZZZ <printf>: ZZZ: inc vectorFlag[2] ZZZ: break ZZZ: push %rbp ... ZZZ: retq
Dyninst Scalable Tools Workshop
Code coverage
for (auto i : functions) BPatch_arithExpr assign(BPatch_assign, vectorFlag[i], BPatch_constExpr(1)); BPatch_breakPointExpr bp; addrSpace->insertSnippet(assign,point) addrSpace->insertSnippet(bp,point) vectorFlag = addrSpace()->malloc(n) functions = addrSpace->getProcedures()
While(process != terminated){ // continueExecution() // WaitForStatusChange() // Program at breakpoint // Copy from mutatee to mutator vectorFlag For(int i = 0; i < vectorFlag.size(); i++) If (vectorFlag[i] == 1) addrSpace->deleteSnippet(assign) addrSpace->deleteSnippet(bp) } XXX <add>: XXX: inc vectorFlag[0] XXX: break XXX: push %rbp ... XXX: retq YYY <sub>: YYY: inc vectorFlag[1] YYY: break YYY: push %rbp ... YYY: retq ZZZ <printf>: ZZZ: push %rbp ... ZZZ: retq
Dyninst Scalable Tools Workshop
Code coverage (basic block)
for (auto i : functions) add->getCFG()->getAllBasicBlocks(blocks) for(auto block : blocks) BPatch_arithExpr assign(BPatch_assign, vectorFlag[i], BPatch_constExpr(1)); BPatch_breakPointExpr bp; addrSpace->insertSnippet(assign,point) addrSpace->insertSnippet(bp,point)
vectorFlag = addrSpace()->malloc(m)
While(process != terminated){ // continueExecution() // WaitForStatusChange() // Program at breakpoint // Copy from mutatee to mutator vectorFlag For(int i = 0; i < vectorFlag.size(); i++) If (vectorFlag[i] == 1) addrSpace->deleteSnippet(assign) addrSpace->deleteSnippet(bp) } m = for each function -> number of basic blocks
Dyninst Scalable Tools Workshop
42
Dyninst Scalable Tools Workshop
Thanks to contributions from:
43
Dyninst Scalable Tools Workshop
Dyninst is used by:
Not on this list? Let us know!
44
Dyninst Scalable Tools Workshop
45
Dyninst Scalable Tools Workshop
46
Dyninst Scalable Tools Workshop
47