1. USING GDB INTERMEDIATE SOFTWARE DESIGN SPRING 2011 DEBUGGING WITH GDB 1.1 HOW DO I RUN PROGRAMS WITH THE DEBUGGER? - PDF

Please download to get full document.

View again

of 14
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Information Report
Category:

Business & Economics

Published:

Views: 10 | Pages: 14

Extension: PDF | Download: 0

Share
Related documents
Description
CS 251 INTERMEDIATE SOFTWARE DESIGN SPRING 2011 Debugging with gdb Checking memory leaks with Valgrind 2 DEBUGGING WITH GDB 1. USING GDB 1.1 HOW DO I RUN PROGRAMS WITH THE DEBUGGER? When you compile your
Transcript
CS 251 INTERMEDIATE SOFTWARE DESIGN SPRING 2011 Debugging with gdb Checking memory leaks with Valgrind 2 DEBUGGING WITH GDB 1. USING GDB 1.1 HOW DO I RUN PROGRAMS WITH THE DEBUGGER? When you compile your program, you must tell the compiler to produce a program that is compatible with the debugger. The debugger needs special information to run properly. To do this, you must compile your program with the debugger flag, -g. This step is critical. Without it, the debugger won't have the program symbol information. That means it won't know what your functions and variables are called, and it won't understand when you ask it about them. 3 First start the debugger with your program name as the first argument. prompt gdb programname Next use the run command in gdb to start execution. Pass your arguments to this command. run arg1 arg2 1.2 HOW DO I RESTART A PROGRAM RUNNING IN THE DEBUGGER? Use the kill command in gdb to stop execution. The you can use the run command as shown above to start it again. kill Kill the program being debugged? (y or n) y run HOW DO I EXIT THE DEBUGGER? Use the quit command. quit NOTE: You may be asked if you want to kill the program. Answer yes. quit The program is running. Exit anyway? (y or n) y prompt EXECUTION OF THE PROGRAM Gdb functions somewhat like an interpreter for your programs. You can stop your program at any time by sending it signals. (Ctrl-C for the interrupt signal SIGINT). Gdb traps this signal and stops executing your program. Also, using breakpoints you can have your program stop executing at any line of code or function call. Once your program is stopped, you can examine 'where' it is in your code. You can look at the variables currently in scope. You can also change variables and memory to see what effect it has on your code HOW DO I STOP/CONTINUE EXECUTION? You can stop execution by sending your program UNIX symbols like SIGINT. This is done using the Ctrl-C key combination. In the following example, I pressed Ctrl-C after 'Starting Program...' appeared. run Starting Program: /home/ug/ryansc/a.out Program received signal SIGINT, Interrupt. 0x80483b4 in main(argc=1, argv=0xbffffda4) at loop.c:5 5 while(1){... Use the continue command to restart execution of your 8 program whenever it is stopped. 2 2.2 HOW DO I SEE WHERE MY PROGRAM STOPPED? Use the list commandtohavegdbprintoutthelinesof code above and below the line the program is stopped at. In the example below, the breakpoint is on line 8. list 3 int main(int argc, char **argv) 4 { 5 int x = 30; 6 int y = 10; 7 8 x = y; 9 10 return 0; HOW DO I STEP THROUGH MY CODE LINE-BY-LINE? First stop your program by sending it signals or using breakpoints. Then use the next and step commands. 5 while(1){ next 7 10 The next command: 11 fun1(); next HOW DO I EXAMINE VARIABLES? Use the print command with a variable name as the argument. For example, if you have int x and char *s: The step command: 11 fun1(); step; fun1 () at loop.c:5 5 return 0; 11 print x $1 = 900 print s $3 = 0x Hello World!\n 12 3 2.5 HOW DO I MODIFY VARIABLES? Use the set command with a C assignment statement as the argument. For example, to change int x to have the value 3: set x = 3 print x $4 = HOW DO I RETURN FROM A FUNCTION? Use the finish command to have a function finish executing and return to it's caller. This command also shows you what value the function returned. finish Run till exit from #0 fun1 () at test.c:5 main (argc=1, argv=0xbffffaf4) at test.c:17 17 return 0; Value returned is $1 = CALL STACK Thecallstackiswherewefindthestackframesthat control program flow. When a function is called, it creates a stack frame that tells the computer how to return control to its caller after it has finished executing. Stack frames are also where local variables and function arguments are 'stored'. We can look at these stack frames to determine how our program is running. Finding the list of stack frames below the current frame is called a backtrace HOW DO I GET A BACKTRACE? Use the gdb command backtrace. In the backtrace below, we can see that we are currently inside func2(), which was called by func1(), which was called from main() backtrace #0 func2 (x=30) at test.c:5 #1 0x80483e6 in func1 (a=30) at test.c:10 #2 0x in main (argc=1, argv=0xbffffaf4) at test.c:19 #3 0x40037f5c in libc_start_main () from /lib/libc.so 3.2 HOW DO I CHANGE STACK FRAMES? Use the gdb command frame. Notice in the backtrace above that each frame has a number beside it. Pass the number of the frame you want as an argument to the command. frame 2 #2 0x in main (argc=1, argv=0xbffffaf4) at test.c:19 19 x = func1(x); 3.3 HOW DO I EXAMINE STACK FRAMES? To look at the contents of the current frame, there are 3 useful gdb commands. info frame displays information about the current stack frame, info locals displays the list of local variables and their values for the current stack frame, info args displays the list of arguments info frame Stack level 2, frame at 0xbffffa8c: eip = 0x in main (test.c:19); saved eip 0x40037f5c called by frame at 0xbffffac8, caller of frame at 0xbffffa5c source language g c. Arglist at 0xbffffa8c, args: argc=1, argv=0xbffffaf4 Locals at 0xbffffa8c, Previous frame's sp is 0x0 Saved registers: ebp at 0xbffffa8c, eip at 0xbffffa90 19 info locals x = 30 s = 0x Hello World!\n info args argc = 1 argv = (char **) 0xbffffaf4 20 5 4. BREAKPOINTS Breakpoints are a way of telling gdb that you want it to stop your program at certain lines of code. You can also have it stop when your program makes specific function calls. Once the program is stopped, you can poke around in memory and see what the values of all your variables are, examine the stack,andstepthrough your program's execution. 4.1 HOW DO I SET A BREAKPOINT ON A LINE? The command to set a breakpoint is break. If you only have one source file, you can set a breakpoint like so: break 19 Breakpoint 1 at 0x80483f8: file test.c, line 19 If you have more than one file, you must give the break command a filename as well: break test.cpp:19 Breakpoint 2 at 0x80483f8: file test.c, line HOW DO I SET A BREAKPOINT ON A C/C++ FUNCTION? To set a breakpoint on a C function, pass its name to break. break func1 Breakpoint 3 at 0x80483ca: file test.c, line 10 Setting a breakpoint on a C++ function is similar to setting a breakpoint on a C function. However C++ is polymorphic, so you must tell break which version of the function you want to break on (even if there is only one). To do this, you tell it the list of argument types. 4.3 HOW DO I GET A LIST OF BREAKPOINTS? Use the info breakpoints command. info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y 0x080483c3 in func2 at test.c:5 3 breakpoint keep y 0x080483da in func1 at test.c:10 break TestClass::testFunc(int) Breakpoint 1 at 0x80485b2: file cpptest.cpp, 23 line 4.4 HOW DO I DISABLE BREAKPOINTS? Use the disable command. Pass the number of the breakpoint youwishtodisableasanargumenttothiscommand.inthe example below we can see that breakpoint number 2 has been disabled (there is an 'n' under the Enb column). (GDB) disable 2 info breakpoints Num Type Disp Enb Address What 2 breakpoint keep n 0x080483c3 in func2 at test.c:5 3 breakpoint keep y 0x080483da in func1 at test.c: HOW DO I SKIP BREAKPOINTS? To skip a breakpoint a certain number of times, we use the ignore command. The ignore command takes two arguments: the breakpoint number to skip, and the number of times to skip it. ignore 2 5 Will ignore next 5 crossings of breakpoint WATCHPOINTS Watchpoints are similar to breakpoints. It is difficult to understand watchpoint commands by themselves, so the following simple example program will be used in the command usage examples. However, watchpoints are not set for functions or lines of code. Watchpoints are set on variables. When those variables are read or written, the watchpoint is triggered and program execution stops. 27 #include stdio.h int main(int argc, char **argv) { int x = 30; int y = 10; x = y; return 0; 28 7 5.1 HOW DO I SET A WRITE WATCHPOINT FOR A VARIABLE? Use the watch command. The argument to the watch command is an expression that is evaluated. This implies that the variable you want to set a watchpoint on must be in the current scope. So, to set a watchpoint on a non-global variable, you must have set a breakpoint that will stop your program when the variable is in scope. You set the watchpoint after the program breaks. watch x Hardware watchpoint 4: x c Continuing. Hardware watchpoint 4: x Old value = New value = 11 main (argc=1, argv=0xbffffaf4) at test.c:10 10 return 0; HOW DO I SET A READ WATCHPOINT FOR A VARIABLE? Use the rwatch command. Usage is identical to the watch command. rwatch y Hardware read watchpoint 4: y continue Continuing. Hardware read watchpoint 4: y Value = main (argc=1, argv=0xbffffaf4) at test.c:8 8 x = y; HOW DO I DISABLE WATCHPOINTS? Active watchpoints show up the breakpoint list. Use the info breakpoints command to get this list. Then use the disable command to turn off a watchpoint, just like disabling a breakpoint. info breakpoints Num Type Disp Enb Address What Num Type Disp Enb Address What 1 breakpoint keep y 0x080483c6 in main at test.c:5 breakpoint already hit 1 time 4 hw watchpoint keep y x breakpoint already hit 1 time disable EXAMPLE 1 EXAMPLE 2 Infinite loop gdb1.cpp Segmentation fault gdb2.cpp GETTING VALGRIND Installation should be as simple as decompressing and untarring using bzip2 (XYZ is the version number in the below examples) bzip2 -d valgrind-xyz.tar.bz2 tar -xf valgrind-xyz XYZ.tar 35 CHECKING MEMORY LEAKS WITH VALGRIND which will create a directory called valgrind-xyz; change into that directory and run./configure make make install 36 9 2. FINDING MEMORY LEAKS WITH VALGRIND Memory leaks are among the most difficult bugs to detect because they don't cause any outward problems until you've run out of memory and your call to malloc suddenly fails. In fact, when working with a language like C or C++ that doesn't have garbage collection, almost half your time might be spent handling correctly freeing memory. And even one mistake can be costly if your program runs for long enough and follows that branch of code. 37 When you run your code, you'll need to specify the tool you want to use; simply running valgrind will give you the current list. We'll focus mainly on the memcheck tool for this tutorial as running valgrind with the memcheck tool will allow us to check correct memory usage. 38 With no other arguments, Valgrind presents a summary of calls to free and malloc: (Note that is the process id on my system; it will differ between runs.) % valgrind --tool=memcheck program_name... =18515== malloc/free: in use at exit: 0 bytes in 0 blocks. ==18515== malloc/free: 1 allocs, 1 frees, 10 bytes allocated. ==18515== For a detailed leak analysis, rerun with: --leak-check=yes 39 If you have a memory leak, then the number of allocs and the number of frees will differ (you can't use one free to release the memory belonging to more than one alloc). If the number of allocs differs from the number of frees, you'll want to rerun your program again with the leakcheck option. This will show you all of the calls to malloc/new/etc that don't have a matching free For demonstration purposes, I'll use a really simple program that I'll compile to the executable called example1 #include stdlib.h int main() { char *x = new char[100]; return 0; 41 % valgrind --tool=memcheck --leak-check=yes example1 ==2116== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==2116== at 0x1B900DD0: malloc (vg_replace_malloc.c:131) ==2116== by 0x804840F: main (in /home/cprogram/example1) This shows what ll have if you don t use the g flag when compiling 42 % valgrind --tool=memcheck --leak-check=yes example1 ==2330== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==2330== at 0x1B900DD0: malloc (vg_replace_malloc.c:131) ==2330== by 0x804840F: main (example1.c:5) Now we know the exact line where the lost memory was allocated. 43 Although it's still a question of tracking down exactly when you want to free that memory, at least you know where to start looking. And since for every call to malloc or new, you should have a plan for handling the memory, knowing where the memory is lost will help you figure out where to start looking. There will be times when the --leak-check=yes option will not result in showing you all memory leaks. To find absolutely every unpaired call to free or new, you'll need to use the --show-reachable=yes option. Its output is almost exactly the same, but it will show more unfreed memory 2. FINDING INVALID POINTER USE WITH VALGRIND Let s see example2 Valgrind can also find the use of invalid heap memory using the memcheck tool. For instance, if you allocate an array with malloc or new and then try to access a location past the end of the array, Valgrind will detect it. #include stdlib.h int main() { char *x =new char[10]; x[10] = 'a'; return 0; What this tell us is that we're using a pointer allocated room for 10 bytes, outside that range -- consequently, we have an 'Invalid write'. Running example2, through Valgrind with valgrind --tool=memcheck --leak-check=yes example2 If we were to try to read from that memory, we'd be alerted to an 'Invalid read of size X', where X is the amount of memory we try to read. (For a char, it'll be one, and for an int, it would be either 2 or 4, depending on your system.) As usual, Valgrind prints the stack trace of function calls so that we know exactly where the error occurs. 47 results in the following warning ==9814== Invalid write of size Invalid write of size 1 ==9814== at 0x804841E: main (example2.c:6) ==9814== Address 0x1BA3607A is 0 bytes after a block of size 10 alloc'd ==9814== at 0x1B900DD0: malloc (vg_replace_malloc.c:131) ==9814== by 0x804840F: main (example2.c:5) 48 12 3. DETECTING THE USE OF UNINITIALIZED VARIABLES Another type of operation that Valgrind will detect is the use of an uninitialized value in a conditional statement. Although you should be in the habit of initializing all variables that you create, Valgrind will help find those cases where you don't. 49 Example3 #include iostream int main() { int x; if(x == 0) { std::cout x is zero std::endl; return 0; 50 Running example3 through Valgrind will result in Running example3 through Valgrind will result in ==17943== Conditional jump or move depends on uninitialised value(s) ==17943== at 0x804840A: main (example3.c:6) ==17943== Conditional jump or move depends on uninitialised value(s) ==17943== at 0x804840A: main (example3.c:6) If a variable is assigned the value of an uninitialized variable, Valgrind will tell you that variable is still in an uninitialized state. The previous example will give #include stdio.h int foo(int x) { if(x 10) { printf( x is less than 10\n ); int main() { int y; foo(y); 53 ==4827== Conditional jump or move depends on uninitialised value(s) ==4827== at 0x : foo (example4.c:5) ==4827== by 0x : main (example4.c:14) WHAT ELSE WILL VALGRIND FIND? Valgrind will detect a few other improper uses of memory: if you call free twice on the same pointer value, Valgrind will detect this for you; you'll get an error Invalid free() along with the corresponding stack trace. In C++ there are three basic options for freeing dynamic memory: free, delete, and delete[]. The free function should only be matched with a call to malloc, delete with new and delete[] with new[]. If you do trigger one of these problems, you'll get this error: Mismatched free()/delete/delete[] which really should be fixed even if your code happens 55 to be working. EXAMPLE valgrind.cpp 56 14
Recommended
View more...
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks