Debugging with GDB

A debugger lets you pause a program, examine and change variables, and step through code. Spend a few hours to learn one so you can avoid dozens of hours of frustration in the future. This is a quick guide, more information here:

Getting Started: Starting and Stopping

gcc -g myprogram.c

Compiles myprogram.c with the debugging option (-g). You still get an a.out, but it contains debugging information that lets you use variables and function names inside GDB, rather than raw memory locations (not fun).

gdb a.out

Opens GDB with file a.out, but does not run the program. You’ll see a prompt (gdb) – all examples are from this prompt.

r

r arg1 arg2

r < file1

Three ways to run “a.out”, loaded previously. You can run it directly (r), pass arguments (r arg1 arg2), or feed in a file. You will usually set breakpoints before running.

help

h breakpoints

List help topics (help) or get help on a specific topic (h breakpoints). GDB is well-documented.

q – Quit GDB

Stepping Through Code

Stepping lets you trace the path of your program, and zero in on the code that is crashing or returning invalid input.

l

l 50

l myfunction

List 10 lines of source code for current line (l), a specific line (l 50), or for a function (l myfunction).

next

Run program until next line, then pause. If the current line is a function, execute the entire function, then pause. Next is good for walking through your code quickly.

step

Run the next instruction, not line. If the current instructions is setting a variable, it is the same as next. If it’s a function, it will jump into the function, execute the first statement, then pause. Step is good for diving into the details of your code.

finish

Finish executing the current function, then pause (also called step out). Useful if you accidentally stepped into a function.

Breakpoints and Watchpoints

Breakpoints are one of the keys to debugging. They pause (break) a program when it reaches a certain location. You can examine and change variables, then resume execution. This is helpful when seeing why certain inputs fail, or testing inputs.

break 45

break myfunction

Set a breakpoint at line 45, or at myfunction. The program will pause when it reaches the breakpoint.

watch x == 3

Set a watchpoint, which pauses the program when a condition changes (when x == 3 changes). Watchpoints are great for certain inputs (myPtr != NULL) without having to break on every function call.

continue

Resume execution after being paused by a breakpoint/watchpoint. The program will continue until it hits the next breakpoint/watchpoint.

delete N

Delete breakpoint N (breakpoints are numbered when created).

Setting Variables and Calling Functions

Viewing and changing variables at run-time is a huge part of debugging. Try giving functions invalid inputs or running other test cases to find the root of problems. Typically, you will view/set variables when the program is paused.

print x

Print current value of variable x. Being able to use the original variable names is why the (-g) flag is needed; programs compiled regularly have this information removed.

set x = 3

set x = y

Set x to a set value (3) or to another variable (y)

call myfunction()

call myotherfunction(x)

call strlen(mystring)

Call user-defined or system functions. This is extremely useful, but beware calling buggy functions.

display x

undisplay x

Constantly display value of variable x, which is shown after every step or pause. Useful if you are constantly checking for a certain value. Use undisplay to remove the constant display.

Backtrace and Changing Frames

The stack is a list of the current function calls – it shows you where you are in the program. A frame stores the details of a single function call, such as the arguments.

bt

Backtrace, aka print the current function stack to show where you are in the current program. If main calls function a(), which calls b(), which calls c(), the backtrace is

c <= current location
b
a
main

bt full – backtrace, including local variables

up

down

Move to the next frame up or down in the function stack. If you are in c, you can move to b or a to examine local variables.

return

Return from current function.

Crashes and Core Dumps

A “core dump” is a snapshot of memory at the instant the program crashed, typically saved in a file called “core”. GDB can read the core dump and give you the line number of the crash, the arguments that were passed, and more. This is very helpful, but remember to compile with (-g) or the core dump will be difficult to debug.

gdb myprogram core

Debug myprogram with “core” as the core dump file.

bt

Print the backtrace (function stack) at the point of the crash. Examine variables using the techniques above.

Handling Signals

Signals are messages thrown after certain events, such as a timer or error. GDB may pause when it encounters a signal; you may wish to ignore them instead.

handle [signalname] [action]

handle SIGUSR1 nostop

handle SIGUSR1 noprint

handle SIGUSR1 ignore

Tell GDB to ignore a certain signal (SIGUSR1) when it occurs. There are varying levels of ignoring.

Integration with Emacs

The Emacs text editor integrates well with GDB. Debugging directly inside the editor is great because you can see an entire screen of code at a time. Use M-x gdb to start a new window with GDB and learn more here.

Tips

I often prefer watchpoints to breakpoints. Rather than breaking on every loop and checking a variable, set a watchpoint for when the variable gets to the value you need (i == 25, ptr != null, etc.).

printf works well for tracing. But wrap printf in alog function for flexibility.

Try passing a log level with your message (1 is most important, 3 is least). You can tweak your log function to send email on critical errors, log to a file, etc.

Code speaks, so here it is. Use #define LOG_LEVEL LOG_WARN to display warnings and above. Use #define LOG_LEVEL LOG_NONE to turn off debugging.

Leave a Reply

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

thank you for this short tut, it’s very helpful.
It would be good if you make another one to us how to integrate the debugger in the source code (#define …)

Vote Up0Vote Down Reply

10 years 3 months ago

Frodo

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

The article was clear and easy to follow. Thank you. But actually, the step command executes all the statements in a line (e.g. “a=5;a+=1;”), it’s a line step (“Run the next instruction, not line.”). For stepping on (machine) instructions the stepi command should be used. As far as I know, stepping on source level instructions/statements is not possible. Correct me, if I’m wrong. :)

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Thanks Frodo, didn’t know they had GNU tools in the shire :)

Great catch, I’ll update the article. Nejd, I’ll put up some examples of the debugging too, thanks.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

[…] ψ Debugging With Gdb Betterexplained – List of all available sources from internet on : Debugging With Gdb Betterexplained […]

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Nice article. I just wrote a debugging article dedicated to hit breakpoints. Check it out and do give it a read if you get time.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

How I can change the value of a local or global variable in gdb?

Vote Up0Vote Down Reply

8 years 9 months ago

Mike

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Beautiful GDB tut, easy, precise, and to the point, def the best for quick no brainer questions!

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

More tips that make gdb more bearable:

1. You can set conditions on breakpoints. E.g. “cond 3 (x==2)” will stop at breakpoint 3 only when x==2.

2. You can set ignore count on breakpoints. “ignore 3 1000” ignores the next 1000 crossing of breakpoint 3. Then at some interesting point in time (when your program crashes…), “info break 3” shows exactly how many times breakpoint 3 had been hit. Next time set the ignore count to one less than that number and gdb will stop one iteration before the crash…

3. When using “watch”, make sure gdb says “hardware watchpoint set”. Unlike software watchpoints, these do not slow down program execution.

4. It is possible to define macros (using define xxx … end) in .gdbrc

Other useful features I haven’t used:

1. gdb7 supports reverse debugging

2. gdb7 is scriptable using Python. Together with the new libstdc++ you get pretty printing of C++ STL collection classes.

Vote Up1Vote Down Reply

7 years 8 months ago

Anonymous

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

@Anonymous: The gdb command line help indicates you can only load a single file.

Vote Up0Vote Down Reply

6 years 10 months ago

Virender Kashyap

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

I have been using gdb minimally. but some of the extra info here is really hepful. Thanks for the turorial.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Great article.

Vote Up0Vote Down Reply

6 years 8 months ago

Paul

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

thanks, gdb tutorial really helped.

Vote Up0Vote Down Reply

6 years 2 months ago

rajesh

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

[…] is just a note on my experiences with gdb. You can look at tutorials from betterexplained.com and RMS for more […]

Vote Up0Vote Down Reply

5 years 10 months ago

Dhanunjay

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

@Dhanunjay: Glad you liked it!

Vote Up0Vote Down Reply

5 years 8 months ago

noname

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

Click to flag and open «Comment Reporting» form. You can choose reporting category and send message to website administrator. Admins may or may not choose to remove the comment or block the author. And please don't worry, your report will be anonymous.

[…] Trace Function Calls Using GDB Revisited! Published on December 17, 2012 in gdb. 0 Comments In an earlier post I discussed how to trace calls using GDB so that function calls and their arguments can easily be viewed. What I neglected to mention was rbreak , a feature of GDB to be able to set breakpoints using a regular expression. Using rbreak you can get the same functionality but with much less effort. For example, to get the same behavior as before (setting a breakpoint on each function call and printing a trace of the bottom most level) all you need to provide to GDB are the following commands: set args 4 10 rbreak file.c:. command silent backtrace 1 continue end run I have placed these commands in a file called gdb_commands. The rbreak command above tells GDB to set a breakpoint on any function call within file.c. With a quick call to GDB we find almost the exact same functionality as we had before. dustymabe@laptop: gdbpost>gdb -quiet -command=gdb_commands ./a.out Reading symbols from /content/gdbpost/a.out…done. Breakpoint 1 at 0x400578: file file.c, line 12. int main(int, char **); Breakpoint 2 at 0x400546: file file.c, line 7. int modulo(int, int); Breakpoint 3 at 0x40055f: file file.c, line 8. int plus(int, int); Breakpoint 4 at 0x400533: file file.c, line 6. int squared(int); #0 main (argc=3, argv=0x7fffffffe698) at file.c:12 #0 squared (x=4) at file.c:6 #0 squared (x=10) at file.c:6 #0 modulo (x=100, y=16) at file.c:7 #0 plus (x=100, y=100) at file.c:8 #0 modulo (x=200, y=16) at file.c:7 #0 plus (x=200, y=100) at file.c:8 #0 modulo (x=300, y=16) at file.c:7 #0 plus (x=300, y=100) at file.c:8 #0 modulo (x=400, y=16) at file.c:7 LCM is 400 [Inferior 1 (process 1579) exited with code 013] Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 (gdb) quit In my previous example, if you had 50 functions that you wanted to trace, you needed 50 break commands as well as 50 command blocks. Considering this fact, it is apparent that rbreak is much more efficient and friendly for when you are setting breakpoints from the GDB cli. Another extremely useful feature is that it also works for c++ classes, so you can break on any function in a class regardless of what file the function is defined in. To show an example of this I converted all the math function calls from the program in file.c to a c++ class. I put the result in a file called file.cc (shown below). #include &ltstdio.h&gt #include &ltstdlib.h&gt // A program that will square two integers and then find the LCM // of the resulting two integers. class Math { public: int squared(int x) { return x*x; } int modulo(int x, int y) { return x%y; } int plus(int x, int y) { return x+y; } }; int main(int argc, char *argv[]) { int x, y, x2, y2, tmp; if (argc != 3) return 0; Math* m = new Math; x = atoi(argv[1]); y = atoi(argv[2]); x2 = m->squared(x); y2 = tmp = m->squared(y); while (1) { if (m->modulo(tmp,x2) == 0) break; tmp = m->plus(tmp,y2); } printf("LCM is %dn", tmp); } I then used the rbreak Math:: command in the following GDB commands file (I named this one gdb_commands2) to run GDB and set up the break points. set args 4 10 rbreak Math:: command silent backtrace 1 continue end run And.. Here we are with the final result: dustymabe@laptop: gdbpost>gdb -quiet -command=gdb_commands2 ./a.out Reading symbols from /content/gdbpost/a.out…done. Breakpoint 1 at 0x400758: file file.cc, line 9. int Math::modulo(int, int); Breakpoint 2 at 0x400776: file file.cc, line 10. int Math::plus(int, int); Breakpoint 3 at 0x400741: file file.cc, line 8. int Math::squared(int); #0 Math::squared (this=0x601010, x=4) at file.cc:8 #0 Math::squared (this=0x601010, x=10) at file.cc:8 #0 Math::modulo (this=0x601010, x=100, y=16) at file.cc:9 #0 Math::plus (this=0x601010, x=100, y=100) at file.cc:10 #0 Math::modulo (this=0x601010, x=200, y=16) at file.cc:9 #0 Math::plus (this=0x601010, x=200, y=100) at file.cc:10 #0 Math::modulo (this=0x601010, x=300, y=16) at file.cc:9 #0 Math::plus (this=0x601010, x=300, y=100) at file.cc:10 #0 Math::modulo (this=0x601010, x=400, y=16) at file.cc:9 LCM is 400 [Inferior 1 (process 2304) exited normally] Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 libgcc-4.7.0-5.fc17.x86_64 libstdc++-4.7.0-5.fc17.x86_64 (gdb) quit Enjoy! Dusty PS – If you are new to GDB I have found a great reference for beginners here . […]