1 / 42

Debugger

Debugger. Objectives. Background Basic C issues Tools and Techniques Programs. Debug !!. If it ain’t broke, don’t fix it. Ronald Reagan If we can’t fix it, it ain’t broke. Lt. Col. Walter Weir. Noticing and Understanding bugs. Before you can debug, you need bugs!

kleinm
Download Presentation

Debugger

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Debugger Ritu Chaturvedi 60-321

  2. Objectives • Background • Basic C issues • Tools and Techniques • Programs Ritu Chaturvedi 60-321

  3. Debug !! • If it ain’t broke, don’t fix it. Ronald Reagan • If we can’t fix it, it ain’t broke. Lt. Col. Walter Weir Ritu Chaturvedi 60-321

  4. Noticing and Understanding bugs Before you can debug, you need bugs! • How can you tell if your code is buggy? • You need testing! Ritu Chaturvedi 60-321

  5. Types of bugs  What kinds of bugs are there? • Syntax errors • Caught by the compiler • Build errors • Makefiles can help • Semantic errors • Uninitialized variables, dead code, typingwrong variables, pointer errors Ritu Chaturvedi 60-321

  6. Common C errors Common C errors result from: • Preprocessing • Macro expansion • System dependencies • System call availability and definitions • Size and representation of types, use sizeof() • Explicit memory management • Using unallocated or deallocated memory • Name space issues • Use static keyword, minimize use of globals Ritu Chaturvedi 60-321

  7. Debugging techniques  Techniques include (but are not limited to): • Compiler features • Warnings (-Wtype) • Optimizations (-Ox) • printf() debugging • Assertions • Code walkthrough • Debugging tools Ritu Chaturvedi 60-321

  8. printf() debugging  Very common, but there are disadvantages: • Output is relatively very slow • Ad-hoc code addition and removal • stdout is buffered and may be lost Solutions: • Use macros to encapsulate debug printf’s • Use stderr for debugging output Ritu Chaturvedi 60-321

  9. printf() debugging  • Use macros to encapsulate debug printf’s Ritu Chaturvedi 60-321

  10. Assertions • The verb "assert" has 4 senses literally • 1. assert, maintain -- (state categorically) • 2. affirm, verify, assert, avow, aver, swan, swear -- (to declare or affirm solemnly and formally as true; "Before God I swear I am innocent") • 3. assert, put forward -- (insist on having one's opinions and rights recognized; "Women should assert themselves more!") • 4. insist, assert -- (assert to be true; "The letter asserts a free society") • When a programmer writes an assert statement he's saying, 'this condition must be true or we have an error'. Ritu Chaturvedi 60-321

  11. Assertions- Always assert that your code is right ! An assertion is a predicate (i.e., a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place. When should you assert ? • whenever you can use it to verify the truth of a situation: • this pointer can never be null • this number is never smaller than zero • this number has to be in the range of 10 and 30 Ritu Chaturvedi 60-321

  12. Assertions • Header <assert.h> • Macro assert() • Tests value of an expression • If 0 (false) prints error message and calls abort • Example: assert( x <= 10 ); • If x is not <= 10, the program will print an error message and abort. Ritu Chaturvedi 60-321

  13. Assertions  • Placing assertions in the code increases the robustness of the code by letting the programmer catch the logic errors in the early stages of the development. • Assertions are generally useful for testing the pre- and post-conditions of a function. - A pre-condition specifies what must be true when a function is invoked. i.e., it is a statement by the programmer that a given function should not be entered unless its pre-condition is guaranteed. If it is entered anyway, the function may behave erratically. In general, pre-conditions depend on global variables and input arguments. - A post-condition specifies what must be true after a function completes successfully. Ritu Chaturvedi 60-321

  14. Assertions #include <stdio.h>#include <assert.h>int checkEligibility (int age, int salary) {assert (age > 21); //preconditionif (salary > 5000) return 1;else return 0;} Ritu Chaturvedi 60-321

  15. Assertions • Assertions are for programmers – not users • Once software is completed and released to end users, the assertions are disabled so that users do not see unexpected, technical messages • To disable assertions, use • #define NDEBUG before #include <assert.h> OR • cc –DNDEBUG …. Ritu Chaturvedi 60-321

  16. Version control  • As we saw in Assignment 2, version control is essential for tracking code changes, enabling groups of developers to collaborate, and backing up code. • Version control is often integrated with bug tracking software – you need to be able to link bugs to specific code revisions. Ritu Chaturvedi 60-321

  17. Debuggers  • Debuggers allow you to monitor other programs as they execute, or to investigate why they crash. Debuggers can: • Start programs with specified arguments • Halt programs on specified conditions • Examine program contents • Change values • Step through code Ritu Chaturvedi 60-321

  18. Compiling for debugging • Normally, an executable file does not contain any references to the original program source code, such as variable names or line-numbers • the executable file is simply the sequence of machine code instructions produced by the compiler. • This is insufficient for debugging, since there is no easy way to find the cause of an error if the program crashes. Ritu Chaturvedi 60-321

  19. Compiling for debugging • GCC provides the -gdebug option to store additional debugging information in object files and executables. • This debugging information allows errors to be traced back from a specific machine instruction to the corresponding line in the original source file. • The debug compilation option works by storing the names and source code line-numbers of functions and variables in a symbol table in the object file or executable. Ritu Chaturvedi 60-321

  20. Compiling for debugging • The execution of a program compiled with -g can also be followed in a debugger like DDD. • Using a debugger allows the values of variables to be examined while the program is running. Ritu Chaturvedi 60-321

  21. GDB • The GNU Debugger is the standard (free) debugger for many Unix systems. • Current version is 6.8 • http://www.gnu.org/software/gdb/ Ritu Chaturvedi 60-321

  22. Using GDB  First compile the program (and all modules) with debugging flags on: luna:~/321>gcc -g debug_me.c -o debug_me Then launch the debugger (from the same directory it was compiled in): luna:~/321>gdb debug_me Ritu Chaturvedi 60-321

  23. Using GDB – breakpoints  Next, run the program in the debugger, supplying the command line arguments: run "hello, world" "goodbye, world" The program will run to completion unless a breakpoint has been set: break debug_me.c:9 (break on line 9) break main (break on function main) Ritu Chaturvedi 60-321

  24. Using GDB – printing  Now you can step through the program: • next – execute command and stop • step – execute command, step into if it is a function, and stop To examine variables, use: • print var The variable must be in scope. You can also display the values of expressions, casts, and functions, e.g.: • print i*2 • print argv[argc] Ritu Chaturvedi 60-321

  25. Some gdb commands Ritu Chaturvedi 60-321

  26. Graphical Tool - DDD • DDD – stands for Data Display Debugger • DDD is a visual interface to the GDB Debugger Ritu Chaturvedi 60-321

  27. Why DDD • Its fast • Its intuitive • I use just printf statements – why do I need a debugger ? • This is like sewing clothes using a needle and thread instead of a sewing machine Ritu Chaturvedi 60-321

  28. Compiling for debugging luna:~/321>gcc -g debug_me.c luna:~/321>ddd a.out & OR luna:~/321>gcc -g debug_me.c –o debug_me luna:~/321>ddd debug_me & Ritu Chaturvedi 60-321

  29. Customizing DDD • Line numbers: Source  Display Line Numbers • Docking toolbars: Edit  Preferences Ritu Chaturvedi 60-321

  30. Setting Breakpoints • If the program has run-time errors e.g. it is stuck in an infinite loop, then we want to set a breakpoint in the while loop • Right-click on the line number of the while loop • Select Set Breakpoint • There should now be a stop-sign at that line Ritu Chaturvedi 60-321

  31. Start the Program • At the top of the screen, select “Run” to start your program • This can also be found in the ‘program’ menu • If DDD asks for arguments to your program, just leave it blank • The program will halt and prompt you for input in the bottom of the window • Enter a small number: something that should finish in less than a second. • It should stop again at the breakpoint. • (The black arrow indicates the next line to be executed) Ritu Chaturvedi 60-321

  32. Next, Hover, and Step • Use Next to move through the program one line at a time • After each Next you can hold your cursor over each variable to see the value • This is called hovering • This always displays the variable’s value at the current line of execution • Note • Step will move down the program, one line at a time. It will also step into function calls if there are any. • Next would also move down one line at a time, but would skip function calls. Ritu Chaturvedi 60-321

  33. Fixing the Bug • So, what’s going wrong? • Leave DDD open • Open the code in your favorite editor • Fix the code • Recompile the code • Run the code (on the command line) • If you wanted to run it again in DDD, you would need to reload the code in DDD Ritu Chaturvedi 60-321

  34. Ritu Chaturvedi 60-321

  35. Website (DDD Tutorial) : Two good tutorials on DDD: http://www.gnu.org/manual/ddd/html_mono/ddd.html http://heather.cs.ucdavis.edu/~matloff/Debug/Debug.pdf Ritu Chaturvedi 60-321

  36. DDD and makefile • If you have a makefile with several dependent files in it and you would like to use DDD, you must compile each file in the make file with the –g option and then open the executable in DDD.

  37. Some Debugging Theory • You have to use breakpoints strategically • Suppose you have 10,000 lines of code with no output and a segmentation fault. Where do you put your breakpoint? The Binary Search Principle of debugging • You don’t look up a word in the dictionary by starting at the first letter ‘A’ page and turning hundreds of pages until you find your word (especially if your word is zebra). • Like searching the dictionary, put a breakpoint in the middle of your program and look at the values there.Is your bug before or after that point? Ritu Chaturvedi 60-321

  38. Examining core files • In addition to allowing programs to be run under the debugger, an important benefit of the -g option is the ability to examine the cause of a program crash from a "core dump". - When a program exits abnormally (i.e. crashes) the operating system can write out a core file (usually named ‘core’) which contains the in-memory state of the program at the time it crashed. This file is often referred to as a core dump. Ritu Chaturvedi 60-321

  39. Examining core files - Combined with information from the symbol table produced by -g, the core dump can be used to find the line where the program stopped, and the values of its variables at that point. - This is useful both during the development of software and after deployment--it allows problems to be investigated when a program has crashed "in the field". Ritu Chaturvedi 60-321

  40. Examining core files Ritu Chaturvedi 60-321

  41. Examining Core Files $ gdb a.out core Core was generated by `./a.out'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x080483ed in foo (p=0x0) at null.c:13 • int y = *p; (gdb) print p $1 = (int *) 0x0 Note:This shows that p is a null pointer (0x0) of type ‘int *’, so we know that dereferencing it with the expression *p in this line has caused the crash. Ritu Chaturvedi 60-321

  42. Displaying a backtrace The debugger can also show the function calls and arguments up to the current point of execution--this is called a stack backtrace and is displayed with the command backtrace: (gdb) backtrace #0 0x080483ed in foo (p=0x0) at null.c:13 #1 0x080483d9 in main () at null.c:7 In this case, the backtrace shows that the crash occurred at line 13 after the function foo was called from main with an argument of p=0x0 at line 7 in ‘null.c’. Ritu Chaturvedi 60-321

More Related