co444h
play

CO444H Ben Livshits 1 Basic Instrumentation Insert additional - PowerPoint PPT Presentation

Runtime monitoring CO444H Ben Livshits 1 Basic Instrumentation Insert additional code into the program This code is designed to record important events as they occur at runtime Some examples A particular function is being hit or


  1. Runtime monitoring CO444H Ben Livshits 1

  2. Basic Instrumentation • Insert additional code into the program • This code is designed to record important events as they occur at runtime • Some examples • A particular function is being hit or a statement is being hit • This leads to function-level or line-level coverage • Each allocation to measure overall memory allocation 2

  3. Levels of Instrumentation • Native code • Instrument machine code • Tools like LLVM are often used for rewriting • Bytecode • Common for languages such as Java and C# • A variety of tools are available for each bytecode format • JoeQ is in this category as well, although it’s a lot more general • Source code • Common for languages like JavaScript • Often the easiest option – parse the code and add more statements 3

  4. Runtime Code Monitoring • Three major examples of monitoring • Purify/Valgrind • Detecting data races • Detecting memory leaks 4

  5. 5 Memory Error Detection

  6. Purify • C and C++ are not type-safe • The type system and the runtime fail to enforce type safety • What are some of the examples? • Possible to read and write outside of your intended data structures • Write beyond loop bounds • Or object bounds • Or overwrite the code pointer, etc. 6

  7. Track Each Byte of Memory • Three states for every byte of tracker memory • Unallocated: cannot be read or written • Allocated but not initialized: cannot be read • Allocated and initialized: all operations are allowed 7

  8. Instrumentation for Purify • Check the state of each byte at every access • Binary instrumentation: • Add code before each load and store • 2 bits per byte of memory (3 different states) • 25% memory overhead as a result (8+2) 8

  9. Red Zones • Leave buffer space between allocated objects that is never allocated – red zones • Red zones are unallocated chunks of memory • Guarantees that walking off the end of an array hits unallocated memory 9

  10. Aging Free Memory • When memory is freed, do not reallocate it immediately • Wait until the memory has “aged” somewhat • This helps with catching dangling pointer errors • Red zones are and aging are easily implemented in the malloc library 10

  11. Summary of Purify • Used quite widely • Started with Purify • Now people use Valgrind • An open-source tool • What is the overhead? • Can you use these in production? 11

  12. 12 Data Race Detection

  13. Data Races • Data races are miltithreaded bugs • At least two threads share a variable or memory location • At least one threat writes to the variable • This is similar to what we did for loop analysis • Races are to be avoided • Typical bug patterns in multithreaded code • Sources of non-determinism • Very hard to reproduce bugs • Why? 13

  14. Not All Races Are Made Equal • We can have data races that involve writes that don’t lead to anything particularly bad • x=1 by two threats – doesn’t matter which one gets to execute first 14

  15. Looking for Data Races • Event A happens before event B if • B follows A in a single thread • A in thread a and B is in thread B, event c such that • c is a sync event after A in a and before B in b • There is a natural partial order on events 15

  16. Early Days of Race Detection • First race tools that is based on happens-before • Monitor all data references • Watch for • Access of v in thread a • Access of v in thread b • No intervening sync between a and b 16

  17. Issues with This Approach • Can be expensive • The approach is fundamentally unsound, i.e. prone to • We need to do a lot of false negatives instrumentation: • Can miss data races • Requires access to all • Needs to be tested with shared variables many execution • All synchronization schedules points 17

  18. What Happens Here? • Thread a • Thread 2 • y=y+1 • lock(m) • lock(m) • unlock(m) • unlock(m) • y=y+1 • How many schedules are there to explore? 18

  19. What Else Can We Do? • What is the proper • Enforce this discipline: programming • Any access to a shared discipline? variable is protected by at least one lock • Most likely, we need to • Any access that is not guard access to shared protected by locks is an variables with locks error 19

  20. Which Lock? • How do we know which • Lock inference: lock protects a • It must be one of the variable? locks that is held at the time of accessing the • A program may have variable many unrelated locks • Initialize C(v) to the set of • Links between shared all locks in the program variables and locks may not be very clear • On access to v by threat t • At runtime, we don’t • C v ← C(𝑤) ∩ 𝑚𝑝𝑑𝑙𝑡_ℎ𝑓𝑚𝑒(𝑢) want to do extensive • If C(v) is empty, print an analysis because of overhead error 20

  21. Complications • It’s not this simple • Uninitialized data • Data initialized by the • We need to think about owner • Uninintialized data • No need to lock access • Read-shared data before initialization • Read-write locks • When does initialization happen? • No good answer at runtime 21

  22. More Complications • Some data is only read • We don’t have to worry about shared reads • We don’t have to update locksets until • More than one thread has the value • At least one thread is writing the value • Keep the lockset algorithm as before but only infer locksets for shared- modified state locations 22

  23. Read-Write Locks • Support a single writer • For each location read but multiple readers • 𝐷 𝑤 ← 𝐷 𝑤 ∩ • Some lock must be held 𝑚𝑝𝑑𝑙𝑡_ℎ𝑓𝑚𝑒(𝑢) either in write mode or read mode for all • For each location write accesses of a shared • 𝐷 𝑤 ← 𝐷 𝑤 ∩ location 𝑥𝑠𝑗𝑢𝑓_𝑚𝑝𝑑𝑙𝑡_ℎ𝑓𝑚𝑒(𝑢) • We separate between read and write mode locks 23

  24. Implementation Details • Instrument the • Every memory word has a shadow word (32 bits) program at the binary • 30 bits designed for the level lockset key • Could also be done at • Sets of locks that are the level of the source encoded using an integer key in a hashtable • Depends on having not many distinct sets of locks • 2 bits for state in the DFA 24

  25. This is the Basis for a Tool Called Eraser • Works quite well • Can find lots of errors with relatively few runs • However, the overhead is dramatic • 10-30x slowdown • Could be optimized with the help of a static analysis 25

  26. 26 Memory Leak Detection

  27. Looking for Memory Leaks • Generally, very difficult to find • They manifest themselves over time • Sometimes, it takes hours or days in a long-running program to find a slow memory leak • An issue in production code when these things are not found in testing 27

  28. Basic Idea • What is a memory leak • Approach: • Look for memory leaks using in Java? techniques that are • Object that haven’t borrowed from garbage been accessed for a collection long time • Any allocated memory that has no more pointers to it is • Track the time of considered to be a leak allocation, track the last • It’s possible to run a garbage access time, periodically collector, don’t free any report unused objects garbage, just detect it and report 28

  29. Difficult in C and C++ • While in Java, we can easily tell what portions of the heap are accessible, in C and C++ that is a difficult task • Some of the possibilities: • No pointers to a malloced block at all – garbage • No pointers to the head of a malloced block – likely garbage • How do we identify what is reachable in C/C++? 29

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