Debuggers Analysis Tools and Profilers Aaron Bloomfield CS

  • Slides: 45
Download presentation
Debuggers, Analysis Tools and Profilers Aaron Bloomfield CS 415 Fall 2005 1

Debuggers, Analysis Tools and Profilers Aaron Bloomfield CS 415 Fall 2005 1

What is a Debugger? “A software tool that is used to detect the source

What is a Debugger? “A software tool that is used to detect the source of program or script errors, by performing step-by-step execution of application code and viewing the content of code variables. ” -MSDN 2

What is a Debugger? (con't) • A debugger is not an IDE – Though

What is a Debugger? (con't) • A debugger is not an IDE – Though the two can be integrated, they are separate entities. • A debugger loads in a program (compiled executable, or interpreted source code) and allows the user to trace through the execution. • Debuggers typically can do disassembly, stack traces, expression watches, and more. 3

Other Forms of Debugging • Periodic printf/cout/print/write/etc. – Statements with relevant information • Assert

Other Forms of Debugging • Periodic printf/cout/print/write/etc. – Statements with relevant information • Assert statements • Desk Checking 4

Why use a Debugger? • No need for precognition of what the error might

Why use a Debugger? • No need for precognition of what the error might be. • Flexible – Allows for “live” error checking – no need to rewrite and re-compile when you realize a certain type of error may be occuring – Dynamic – Can view the entire relevant scope 5

Why people don’t use a Debugger? • With simple errors, may not want to

Why people don’t use a Debugger? • With simple errors, may not want to bother with starting up the debugger environment. – Obvious error – Simple to check using prints/asserts • Hard-to-use debugger environment • Error occurs in optimized code • Changes execution of program (error doesn’t occur while running debugger) 6

Types of Debuggers • Two types of debuggers (really, two types of languages) –

Types of Debuggers • Two types of debuggers (really, two types of languages) – Interpreted language debuggers – Compiled language debuggers • Which do you think is easier to write? 7

Debuggers for Compiled Languages • Harder to implement – Generally, would like information about

Debuggers for Compiled Languages • Harder to implement – Generally, would like information about source code (not normally included in compiled executables) – Work on a lower level • Need special “debug” executables. • More complex, and we'll focus on these. 8

Functions of a Debugger • Disassembly • Execution Tracing/Stack tracing • Symbol watches 9

Functions of a Debugger • Disassembly • Execution Tracing/Stack tracing • Symbol watches 9

Disassembly • Most basic form of debugging • Translating machine code into assembly instructions

Disassembly • Most basic form of debugging • Translating machine code into assembly instructions that are more easily understood by the user. • Typically implementable as a simple lookup table • No higher-level information (variable names, etc. ) • Relatively easy to implement. 10

Execution Tracing • Follows the program through the execution. Users can step through line-by-line,

Execution Tracing • Follows the program through the execution. Users can step through line-by-line, or use breakpoints. • Typically allows for “watches” on – registers, memory locations, symbols • Allows for tracing up the stack of runtime errors (back traces) • Allows user to trace the causes of unexpected behavior and fix them 11

Symbol Information • Problem – a compiler/assembler translates variable names and other symbols into

Symbol Information • Problem – a compiler/assembler translates variable names and other symbols into internally consistent memory addresses • How does a debugger know which location is denoted by a particular symbol? • We need a “debug” executable. 12

Debug vs. Release Builds • Debug builds usually are not optimized • Debug executables

Debug vs. Release Builds • Debug builds usually are not optimized • Debug executables contain: – program's symbol tables – location of the source file – line number tags for assembly instuctions. 13

Profilers 14

Profilers 14

What are they? Time Profilers: – Tells you where your program spent its time

What are they? Time Profilers: – Tells you where your program spent its time – Tells you which functions called which other functions while it was executing 15

What are they? Space Profiler: – Also called “heap profiling” or “memory profiling” –

What are they? Space Profiler: – Also called “heap profiling” or “memory profiling” – Space profiling is useful to help you reduce the amount of memory your program uses. 16

How do they work? Time profiler: – Profiling works by changing how every function

How do they work? Time profiler: – Profiling works by changing how every function in your program is compiled so that when it is called, it will stash away some information about where it was called from. – From this, the profiler can figure out what function called it, and can count how many times it was called 17

How do they work? (2) Space Profiler: – Stops execution and examines the stack

How do they work? (2) Space Profiler: – Stops execution and examines the stack – Stops execution when a page of memory is allocated – Collects Data about which function asked for the memory 18

How do they work? (3) • After the data is collected by the profiler,

How do they work? (3) • After the data is collected by the profiler, an interpreter must be run to display the data in an understandable format • Can be text-based or graphical 19

Why do I need a time profiler? • Find where the program is spending

Why do I need a time profiler? • Find where the program is spending most of it’s time – That’s where you should focus optimization efforts • The program performs the proper functions, but is too slow – Important in real time systems – Important to web applications • The program is too large or too complex to analyze by reading the source 20

Why do I need a space profiler? • The program needs to use a

Why do I need a space profiler? • The program needs to use a fixed amount of memory • The program is too large to conceive of the overall memory usage or how often memory requests are made • Profilers can show the memory usage of libraries used by your program 21

Some Profiler Examples – Time • gprof – GNU Profiler – compile programs with

Some Profiler Examples – Time • gprof – GNU Profiler – compile programs with the –pg option – execute program to generate data – run gprof to interpret the data 22

gprof sample data – Flat Profile Each sample counts as 0. 01 seconds. %

gprof sample data – Flat Profile Each sample counts as 0. 01 seconds. % cumulative self total time seconds calls ms/call name 33. 34 0. 02 7208 0. 00 open 16. 67 0. 03 0. 01 244 0. 04 0. 12 offtime 16. 67 0. 04 0. 01 8 1. 25 memccpy 16. 67 0. 05 0. 01 7 1. 43 write 16. 67 0. 06 0. 01 0. 00 0. 06 0. 00 236 0. 00 tzset 0. 00 0. 06 0. 00 192 0. 00 tolower mcount 23

gprof sample data – Call graph index % time self children called name -----------------------0.

gprof sample data – Call graph index % time self children called name -----------------------0. 00 0. 05 1/1 main [2] [3] 100. 05 1 report [3] 0. 00 0. 03 8/8 timelocal [6] 0. 00 0. 01 1/1 print [9] 0. 00 0. 01 9/9 fgets [12] 0. 00 12/34 0. 00 8/8 lookup [20] 0. 00 1/1 fopen [21] 0. 00 8/8 0. 00 8/16 ------------------------ strncmp <cycle 1> [40] chewtime [24] skipspace [44] 24

Some Profiler Examples – Space • Massif – Space Profiler for C and C++

Some Profiler Examples – Space • Massif – Space Profiler for C and C++ – Provides relative space data on 5 different areas: • • • Heap blocks Heap administration blocks Stack sizes Code size Data size 25

Massif sample data - basic ==1012== Total spacetime: 917, 098, 589 ms. B ==1012==

Massif sample data - basic ==1012== Total spacetime: 917, 098, 589 ms. B ==1012== heap: 0. 0% ==1012== heap admin: 0. 0% ==1012== stack(s): 0. 0% ==1012== static code: 44. 4% ==1012== static data: 55. 3% 26

Massif sample data – Space-time Graph 27

Massif sample data – Space-time Graph 27

Analysis Tools 28

Analysis Tools 28

Purpose of Analysis Tools • Need for a feasible method to catch bugs in

Purpose of Analysis Tools • Need for a feasible method to catch bugs in large projects. Formal verification techniques require unreasonable effort on large projects. • Augment traditional debugging techniques without adding unreasonable burden to the development process. 29

30

30

Two Types of Analysis Tools • Static Analysis • Run-time (dynamic) Analysis 31

Two Types of Analysis Tools • Static Analysis • Run-time (dynamic) Analysis 31

Static Analysis • Examine a program for bugs without running the program. • Examples:

Static Analysis • Examine a program for bugs without running the program. • Examples: – Splint (www. splint. org), – Poly. Space C Verifier (www. polyspace. com). 32

Splint • Open Source Static Analysis Tool developed at U. Va by Professor Dave

Splint • Open Source Static Analysis Tool developed at U. Va by Professor Dave Evans. • Based on Lint. 33

Errors Splint will detect • Dereferencing a possibly null pointer. • Using possibly undefined

Errors Splint will detect • Dereferencing a possibly null pointer. • Using possibly undefined storage or returning storage that is not properly defined. • Type mismatches, with greater precision and flexibility than provided by C compilers. • Violations of information hiding. • Memory management errors including uses of dangling references and memory leaks. • Dangerous aliasing. 34

Errors Splint will detect continued… • Modifications and global variable uses that are inconsistent

Errors Splint will detect continued… • Modifications and global variable uses that are inconsistent with specified interfaces. • Problematic control flow such as likely infinite loops. • Buffer overflow vulnerabilities. • Dangerous macro initializations and invocations. • Violations of customized naming conventions. 35

What’s wrong with this code? void strcpy(char* str 1, char* str 2) { while

What’s wrong with this code? void strcpy(char* str 1, char* str 2) { while (str 2 != 0) { *str 1 = *str 2; str 1++; str 2++; } str 1 = 0; //null terminate the string } 36

What happens to the stack? void foo() { char buff 1[20]; char buff 2[40];

What happens to the stack? void foo() { char buff 1[20]; char buff 2[40]; … //put some data into buff 2 strcpy(buff 1, buff 2); } 37

Secure Programming • Exploitable bugs such as buffer overflows in software the most costly

Secure Programming • Exploitable bugs such as buffer overflows in software the most costly bugs. • Incredibly frequent because they are so hard to catch. • Analysis tools play a big part in finding and fixing security holes in software. 38

How does Splint deal with false positives? • Splint supports annotations to the code

How does Splint deal with false positives? • Splint supports annotations to the code that document assumptions the programmer makes about a given piece of code • These annotations help limit false positives. 39

Run-time Analysis • Many bugs cannot be determined at compile time. Run-time tools required

Run-time Analysis • Many bugs cannot be determined at compile time. Run-time tools required to find these bugs. • Run-time analysis tools work at run-time instead of compile time. • Example – Purify (www. rational. com). 40

Purify • Purify modifies object files at link time. • After execution, Purify will

Purify • Purify modifies object files at link time. • After execution, Purify will report bugs such as memory leaks and null dereferences. 41

Purify continued… • From the purify manual: “Purify checks every memory access operation, pinpointing

Purify continued… • From the purify manual: “Purify checks every memory access operation, pinpointing where errors occur and providing diagnostic information to help you analyze why the errors occur. ” 42

Types of errors found by Purify • Reading or writing beyond the bounds of

Types of errors found by Purify • Reading or writing beyond the bounds of an array. • Using un-initialized memory. • Reading or writing freed memory. • Reading or writing beyond the stack pointer. • Reading or writing through null pointers. • Leaking memory and file descriptors. • Using a pointer whose memory location was just deallocated 43

Static vs. Run-time Analysis • Probably good to use both. • Run-time analysis has

Static vs. Run-time Analysis • Probably good to use both. • Run-time analysis has fewer false positives, but usually requires that a test harness test all possible control flow paths. 44

Cons of Analysis Tools • Add time and effort to the development process. •

Cons of Analysis Tools • Add time and effort to the development process. • Lots of false positives. • No guarantee of catching every bug. • However, in a commercial situation, probably worth your time to use these tools. 45