Presentation is loading. Please wait.

Presentation is loading. Please wait.

Optimizing Your Dyninst Program

Similar presentations


Presentation on theme: "Optimizing Your Dyninst Program"— Presentation transcript:

1 Optimizing Your Dyninst Program
Optimizing Your Dyninst Programs Optimizing Your Dyninst Program Matthew LeGendre Wandering titles Cut out complete sentences, highlight in yellow Inconsistent instrumentation Matthew LeGendre

2 Optimizing Your Dyninst Programs
Optimizing Dyninst Dyninst is being used to insert more instrumentation into bigger programs. For example: Instrumenting every memory instruction Working with binaries 200MB in size Performance is a big consideration What can we do, and what can you do to help? Matthew LeGendre

3 Performance Problem Areas
Optimizing Your Dyninst Programs Performance Problem Areas Parsing: Analyzing the binary and reading debug information. Instrumenting: Rewriting the binary to insert instrumentation. Runtime: Instrumentation slows down a mutatee at runtime. Matthew LeGendre

4 Optimizing Your Dyninst Programs
Optimizing Dyninst Programmer Optimizations Telling Dyninst not to output tramp guards. Dyninst Optimizations Reducing the number of registers saved around instrumentation. More examples (parsing) Matthew LeGendre

5 Optimizing Your Dyninst Programs
Parsing Overview Control Flow Identifies executable regions Data Flow Analyzes code prior to instrumentation Debug Reads debugging information, e.g. line info Symbol Reads from the symbol table Lazy Parsing: Not parsed until it is needed Remove lazy parsing define? Rephrase? Matthew LeGendre

6 Optimizing Your Dyninst Programs
Control Flow Dyninst needs to analyze a binary before it can instrument it. Identifies functions and basic blocks Granularity Parses all of a module at once. Triggers Operating on a BPatch_function Requesting BPatch_instPoint objects Performing Stackwalks (on x86) Explicititly say “triggers”, “granularity” Picture of module/function? Matthew LeGendre

7 Optimizing Your Dyninst Programs
Data Flow Dyninst analyzes a function before instrumenting it. Live register analysis Reaching allocs on IA-64 Granularity Analyzes a function at a time. Triggers The first time a function is instrumented Little redudency here. Use explicit labels. Matthew LeGendre

8 Optimizing Your Dyninst Programs
Debug Information Reads debug information from a binary. Granularity Parses all of a module at once. Triggers Line number information Type information Local variable information Mention “Optional” Allows you to “avoid or defer” Matthew LeGendre

9 Optimizing Your Dyninst Programs
Symbol Table Extracts function and data information from the symbol Granularity Parses all of a module at once. Triggers Not done lazily. At module load. Mention “Optional” Allows you to “avoid or defer” Matthew LeGendre

10 Optimizing Your Dyninst Programs
Lazy Parsing Overview Granularity Triggered By Control Flow Module BPatch_function Queries Data Flow Function Instrumentation Debug Debug Info Queries Symbol Automatically Talking point, symbol table parsing is cheap earlier. Lazy parsing allows you to avoid or defer costs. Matthew LeGendre

11 Inserting Instrumentation
Optimizing Your Dyninst Programs Inserting Instrumentation What happens when we re-instrument a function? foo: 0x1000: push ebp 0x1001: movl esp,ebp 0x1002: push $1 0x1004: call bar 0x1005: leave 0x1006: ret foo: 0x2000: jmp entry_instr 0x2005: push ebp 0x2006: movl esp,ebp 0x2007: push $1 0x2009: call bar 0x200F: leave 0x2010: ret foo: 0x3000: jmp entry_instr 0x3005: push ebp 0x3006: movl esp,ebp 0x3007: push $1 0x3009: jmp call_instr 0x300F: call bar 0x3014: leave 0x3015: ret foo: 0x4000: jmp entry_instr 0x4005: push ebp 0x4006: movl esp,ebp 0x4007: push $1 0x4009: jmp call_instr 0x400F: call bar 0x4014: leave 0x4015: jmp exit_instr 0x401A: ret Use easier to read font. Better highlighting of changes. Laser pointer them. Draw attention away from content, summarize what will talk about Matthew LeGendre

12 Inserting Instrumentation
Optimizing Your Dyninst Programs Inserting Instrumentation Bracket instrumentation requests with: beginInsertionSet() . endInsertionSet() Batches instrumentation Allows for transactional instrumentation Improves efficiency (rewrite) Matthew LeGendre

13 Optimizing Your Dyninst Programs
Runtime Overhead Two factors determine how instrumentation slows down a program. What does the instrumentation cost? Increment a variable Call a cache simulator How often does instrumentation run? Every time read/write are called Every memory instruction Additional Dyninst overhead on each instrumentation point. Frequent instrumentation needs to be inexpensive Matthew LeGendre

14 Runtime Overhead - Basetramps
Optimizing Your Dyninst Programs Runtime Overhead - Basetramps A Basetramp save all GPR save all FPR t = DYNINSTthreadIndex() if (!guards[t]) { guards[t] = true jump to minitramps guards[t] = false } restore all FPR restore all GPR Save Registers Calculate Thread Index Check Tramp Guards Run All Minitramps Boldify Save GPR -> save All GPR Move box down, caption below Cross out things as deleted Restore Registers Matthew LeGendre

15 Runtime Overhead – Registers
Optimizing Your Dyninst Programs Runtime Overhead – Registers A Basetramp save all GPR save all FPR t = DYNINSTthreadIndex() if (!guards[t]) { guards[t] = true jump to minitramps guards[t] = false } restore all FPR restore all GPR Analyzes minitramps for register usage. Analyzes functions for register liveness. Only saves what is live and used. Matthew LeGendre

16 Runtime Overhead – Registers
Optimizing Your Dyninst Programs Runtime Overhead – Registers A Basetramp Called functions are recursively analyzed to a max call depth of 2. save all GPR save all FPR t = DYNINSTthreadIndex() if (!guards[t]) { guards[t] = true jump to minitramps guards[t] = false } restore all FPR restore all GPR minitramp call foo() call bar() Matthew LeGendre

17 Runtime Overhead – Registers
Optimizing Your Dyninst Programs Runtime Overhead – Registers A Basetramp Use shallow function call chains under instrumentation, so Dyninst can analyze all reachable code. Use BPatch::setSaveFPR() to disable all floating point saves. save live GPR t = DYNINSTthreadIndex() if (!guards[t]) { guards[t] = true jump to minitramps guards[t] = false } restore live GPR Save some GPR -> save live GPR Matthew LeGendre

18 Runtime Overhead – Tramp Guards
Optimizing Your Dyninst Programs Runtime Overhead – Tramp Guards A Basetramp Prevents recursive instrumentation. Needs to be thread aware. save live GPR t = DYNINSTthreadIndex() if (!guards[t]) { guards[t] = true jump to minitramps guards[t] = false } Restore live GPR Matthew LeGendre

19 Runtime Overhead – Tramp Guards
Optimizing Your Dyninst Programs Runtime Overhead – Tramp Guards A Basetramp Build instrumentation that doesn’t make function calls (no BPatch_funcCallExpr snippets) Use setTrampRecursive() if you’re sure instrumentation won’t recurse. save live GPR t = DYNINSTthreadIndex() jump to minitramps restore live GPR Matthew LeGendre

20 Runtime Overhead – Threads
Optimizing Your Dyninst Programs Runtime Overhead – Threads A Basetramp Returns an index value (0..N) unique to the current thread. Used by tramp guards and for thread local storage by instrumentation Expensive save live GPR t = DYNINSTthreadIndex() jump to minitramps restore live GPR Matthew LeGendre

21 Runtime Overhead – Threads
Optimizing Your Dyninst Programs Runtime Overhead – Threads A Basetramp Not needed if there are no tramp guards. Only used on mutatees linked with a threading library (e.g. libpthread) save live GPR jump to minitramps restore live GPR Matthew LeGendre

22 Runtime Overhead – Minitramps
Optimizing Your Dyninst Programs Runtime Overhead – Minitramps A Basetramp Minitramps contain the actual instrumentation. What can we do with minitramps? save live GPR jump to minitramps restore live GPR Matthew LeGendre

23 Runtime Overhead – Minitramps
Optimizing Your Dyninst Programs Runtime Overhead – Minitramps Minitramp A Created by our code generator, which assumes a RISC like architecture. Instrumentation linked by jumps. //Increment var by 1 load var -> reg reg = reg + 1 store reg -> var jmp Minitramp B Minitramp B //Call foo(arg1) push arg1 call foo jmp BaseTramp Matthew LeGendre

24 Runtime Overhead – Minitramps
Optimizing Your Dyninst Programs Runtime Overhead – Minitramps Minitramp A New code generator recognizes common instrumentation snippets and outputs CISC instructions. Works on simple arithmetic, and stores. //Increment var by 1 load var -> reg reg = reg + 1 store reg -> var jmp Minitramp B //Increment var by 1 inc var jmp Minitramp B Minitramp B //Call foo(arg1) push arg1 call foo jmp BaseTramp Matthew LeGendre

25 Runtime Overhead – Minitramps
Optimizing Your Dyninst Programs Runtime Overhead – Minitramps Minitramp A Mergetramp New merge tramps combine minitramps together with basetramp. Faster execution, slower re-instrumentation. Change behavior with BPatch::setMergeTramp //Increment var by 1 inc var jmp Minitramp B //Increment var by 1 load var -> reg reg = reg + 1 store reg -> var jmp Minitramp B //Increment var by 1 inc var jmp Minitramp B Minitramp B //Call foo(arg1) push arg1 call foo jmp BaseTramp Matthew LeGendre

26 Optimizing Your Dyninst Programs
Runtime Overhead Where does the Dyninst’s runtime overhead go? 87% Calculating thread indexes 12% Saving registers 1% Trampoline Guards Dyninst allows inexpensive instrumentation to be inexpensive. Piechart Inexp -> Inexp is stupid Matthew LeGendre

27 Optimizing Your Dyninst Programs
Summary Make use of lazy parsing Use insertion sets when inserting instrumentation. Small, easy to understand snippets are easier for Dyninst to optimize. Try to avoid function calls in instrumentation. Matthew LeGendre

28 Optimizing Your Dyninst Programs
Questions? Matthew LeGendre


Download ppt "Optimizing Your Dyninst Program"

Similar presentations


Ads by Google