memory debugging
play

Memory Debugging SS 2007 Johannes Kepler University Linz, Austria - PowerPoint PPT Presentation

Advanced Topics on Applied Systemtheory: Debugging Memory Debugging 1 Memory Debugging SS 2007 Johannes Kepler University Linz, Austria Dr. Toni Jussila Institut for Formal Models and Verification http://fmv.jku.at/kv Applied Systemtheory


  1. Advanced Topics on Applied Systemtheory: Debugging Memory Debugging 1 Memory Debugging SS 2007 Johannes Kepler University Linz, Austria Dr. Toni Jussila Institut for Formal Models and Verification http://fmv.jku.at/kv Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  2. Memory Debugging Memory Debugging 2 • some programming languages (most notably C and C++), leave the management of the heap ∗ to the programmer – you allocate new memory with malloc() / new() – you free allocated memory with free() / delete() • unintentional misuse of this heap memory is a common source of errors • there types of faults are time bombs – they may manifest themselves only millions of instructions later Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz ∗ heap is the place where new objects are allocated

  3. Types of Heap Faults Memory Debugging 3 1. uninitialized memory read resp. copy (umr, umc) 2. using memory that you do not own (a) null pointer read or write (npr, npw) (b) zero page read of write (zpr, zpw) (c) invalid pointer read or write (ipr, ipw) (d) free memory read or write (fmr, fmw) (e) beyong stack read or write (bsr, bsw) Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  4. Types of Heap Faults II Memory Debugging 4 3. using more memory that you have allocated (buffer overruns) (a) array bounds read (abr) (b) array bounds write (abw) 4. using faulty heap memory management (a) memory leaks and potential memory leaks (mlk, plk, mpk) (b) freeing invalid memory (fim) i. freeing mismatched memory (fmm) ii. freeing non-heap memory (fnh) iii. freeing unallocated memory (fum) Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  5. Tools to Detect Memory Faults Memory Debugging 5 • validating the heap with MALLOC CHECK – provided with the GNU C runtime library • avoiding buffer overflows with Electricfence – provided as a library, compile with -lefence • detecting memory errors with Purify (a commercial tool) • detecting memory errors (and profiling) with Valgring Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  6. Purify Memory Debugging 6 • initially written by Reed Hastings and Bob Joyce (1991) • Pure Software ⇒ Pure Atria ⇒ Rational Software ⇒ IBM • OCI = Object Code Instrumentation – compile your programs with debug information (switch -g ) – call Purify with the binary as an argument to instrument it with additional code around calls to malloc() and free() – if you run the instrumented program, Purify detects errors inside of your program or operating system libraries at runtime – program may work, yet Purify may report an error Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  7. Heap Fault Examples I Memory Debugging 7 • NPR – read from address zero • ZPR – try to read an address from memory page zero typedef struct node { struct node* next; int val; } Node; int findLastNodeValue(Node* head) { while (head->next != NULL) { /* Expect NPR */ head = head->next; } return head->val; /* Expect ZPR */ } void genNPRandZPR() { int i = findLastNodeValue(NULL); } Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  8. Heap Fault Examples II Memory Debugging 8 • FMR – read from a memory that is released (dangling pointer) • FMR – write from a memory that is released int* init_array(int *ptr, int new_size) { ptr = (int*) realloc(ptr, new_size*sizeof(int)); memset(ptr, 0, new_size*sizeof(int)); return ptr; } int* fill_fibonacci(int *fib, int size) { int i; /* oops, forgot: fib = */ init_array(fib, size); fib[1] = 1; for (i=2; i<size; i++) fib[i] = fib[i-1] + fib[i-2]; return fib; } void genFMRandFMW() { int *array = (int*)malloc(10); fill_fibonacci(array, 3); } Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  9. Heap Fault Examples III Memory Debugging 9 • BSR – beyond stack read (dangling stack pointer) • BSW – beyong stack write char *append(const char* s1, const char *s2) { const int MAXSIZE = 128; char result[128]; int i=0, j=0; for (j=0; i<MAXSIZE-1 && j<strlen(s1); i++,j++) { result[i] = s1[j]; } for (j=0; i<MAXSIZE-1 && j<strlen(s2); i++,j++) { result[i] = s2[j]; } result[++i] = ’\0’; return result; } void genBSRandBSW() { char *name = append("Applied ", append("System", "theory")); printf("%s\n", name); /* Expect BSR */ *name = ’\0’; /* Expect BSW */ } Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  10. Heap Fault Examples IV – memory leaks Memory Debugging 10 • PLK – potential memory leak int *plk = NULL; void genPLK() { plk = (int *) malloc(2 * sizeof(int)); /* Expect PLK */ plk++; } • FNH – freeing non-heap memory • FUM – freeing unallocated memory void genFNH() { int fnh = 0; free(&fnh); /* Expect FNH: freeing stack memory */ } void genFUM() { int *fum = (int *) malloc(4 * sizeof(int)); free(fum+1); /* Expect FUM: fum+1 points to middle of a block */ free(fum); free(fum); /* Expect FUM: freeing already freed memory */ } Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  11. Valgrind Memory Debugging 11 • named after the holy entrance of Valhalla from Nordic mythology • originally written by Julian Seward (aka the author of bzip2 ) • DBI framework for building heavyweight DBA tools • tool to execute dynamic x86-to-x86 transformations – thus can be combined with different code instrumentation plug-ins – shadow values: for each register and memory value you can introduce additional data Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  12. Valgrind II Memory Debugging 12 • Valgrind runs on the machine’s real CPU • the client (the program to be analyzed) is run on a simulated CPU • Tools: heap bugs can be analyzed with a plug-in called memcheck • cachegrind annotate every line of your program with the number of executed in- structions and incurred cache misses • callgrind get call counts and cost of each call • helgrind spots potential race conditions in your program Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  13. Valgrind III Memory Debugging 13 • uses dynamic binary recompilation (D & R) – machine code is transformed to Valgrind intermediate representation – architecture-neutral, single-static-assignment (SSA) – granularity: superblock (single-entry, multiple-exit) – RISC-like, yet over 200 primitive arithmetic/logical operations • FP , MMX, SSE and SSE2 instructions (on Intel architecture) – not disassembled to the same level of detail as integer instructions • cannot trace into kernel, system calls handled by wrappers 15KLOC of tedious C code Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  14. (Valgrind) + memcheck Memory Debugging 14 • memory definedness checker at the bit level • for each register or memory bit, a shadow V-bit is introduced • every operation that creates a value is shadowed by an operation that computes the V-bits of the output based on those of the input • every operation using a value in a way that could affect observable behavior is checked • example: d3 = Add(d1, d2) is shadowed by v3 = Left(UifU(v1, v2)) • large overhead, programs typically run 20 – 30 times slower Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  15. Memcheck, avoiding false positives Memory Debugging 15 • Memcheck defers error reporting as far as it can. • Checks for undefinedness are made for: 1. memory addresses in load and store instructions 2. conditional jump, check %eflags for definedness 3. arguments to system calls 4. memory loads (address and data) into a SIMD or FP register Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  16. Memcheck – limitations Memory Debugging 16 • cannot be free of both false positives and negatives – equivalent of solving the Halting Problem • design goal: almost completely avoid false negatives and minimize false positives • a worthy aim: Memcheck-cleanness. To get there, dummy initializations may be needed. • Memcheck cannot test for code that is not executed – thus, in addition to ad-hoc debugging, it should be used together with automatic regression test suites Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

  17. Current Trends Memory Debugging 17 • Valgrind and Purify only make sense in environments where heap memory manage- ment is left to the programmer • current trend in software development is to trade performance for runtime safety wherever possible (Zeller) • in Java and .NET the integrity of code and data is constantly verified • given explosion in computational power, the cost of checking becomes more and more irrelevant • eventually, proving correctness may turn to be a strategy for optimization Applied Systemtheory – SS 2007 – Toni Jussila – JKU Linz

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend