How many of you actually use GDB from the terminal?
c - How to debug using gdb? - Stack Overflow
debugging - How do you use gdb to debug your code? - Stack Overflow
Using gdb debugger in an efficient way
Videos
Curious how many of you use raw GDB when debugging C programs. Is it worth learning? Or is it better to find some front end program with buttons / watch-windows etc.?
Here is a quick start tutorial for gdb:
/* test.c */
/* Sample program to debug. */
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
if (argc != 3)
return 1;
int a = atoi (argv[1]);
int b = atoi (argv[2]);
int c = a + b;
printf ("%d\n", c);
return 0;
}
Compile with the -g3 option. g3 includes extra information, such as all the macro definitions present in the program.
gcc -g3 -o test test.c
Load the executable, which now contain the debugging symbols, into gdb:
gdb --annotate=3 test.exe
Now you should find yourself at the gdb prompt. There you can issue commands to gdb. Say you like to place a breakpoint at line 11 and step through the execution, printing the values of the local variables - the following commands sequences will help you do this:
(gdb) break test.c:11
Breakpoint 1 at 0x401329: file test.c, line 11.
(gdb) set args 10 20
(gdb) run
Starting program: c:\Documents and Settings\VMathew\Desktop/test.exe 10 20
[New thread 3824.0x8e8]
Breakpoint 1, main (argc=3, argv=0x3d5a90) at test.c:11
(gdb) n
(gdb) print a
$1 = 10
(gdb) n
(gdb) print b
$2 = 20
(gdb) n
(gdb) print c
$3 = 30
(gdb) c
Continuing.
30
Program exited normally.
(gdb)
In short, the following commands are all you need to get started using gdb:
break file:lineno - sets a breakpoint in the file at lineno.
set args - sets the command line arguments.
run - executes the debugged program with the given command line arguments.
next (n) and step (s) - step program and step program until it
reaches a different source line, respectively.
print - prints a local variable
bt - print backtrace of all stack frames
c - continue execution.
Type help at the (gdb) prompt to get a list and description of all valid commands.
Start gdb with the executable as a parameter, so that it knows which program you want to debug:
gdb ./myprogram
Then you should be able to set breakpoints. For example:
b myfile.cpp:25
b some_function
Some hints:
- use a graphical frontend (kdbg is quite good, ddd is at least better than command-line gdb, kdevelop has a nice gdb frontend but has some bgs, nemiver looks quite nice as well but is still in the works)
- make sure to have debug symbols and source code for all important parts (your own code and also some system libs)
- on RedHat, you can install the -debuginfo packages to make both symbols and source code magically appear in the debugger - really cool because you can looks into libc function calls etc.
- on Debian/Ubuntu, you can install the -dbg packages to get symbols; installing appropriate source files for system packages seems to be difficult, though
- I tend to add assert() and abort() calls in places that should not be reached, or in places that I want to study (some kind of heavy-weight breakpoint)
- ideally the assert() or abort() calls should be wrapped in some method or macro that only enables them in Debug releases, or even better that only enables them if a certain env var is set
- install a signal handler for SIGSEGV and SIGABRT; personally I check if a certain env var is set before installing the handlers; and in the handler I execute a hardcoded external command which usually lives somewhere in ~/.local/bin/; that command might then start kdbg and attach it to the crashing app. Voila, debugger pops up the moment your app does something bad.
- If you use unit tests, you could similarly attach a debugger whenever a test case fails, to inspect the app then.
In general you find something that isn't how it should be, and work backwards until you understand why.
The most obvious is the most useful: Setting a breakpoint on a function or line number and walking through the code line by line.
Another handy tip is to have show functions for all your structures/objects even if they are never used in your program, because you can run these functions from within gdb:
gdb> p show_my_struct(struct)
My custom display of Foo:
...
Watchpoints can be really handy too, but may slow down your program a lot. These break the flow when the value of a variable or address changes.:
gdb> watch foo
Watchpoint4: foo
gdb>
help running provides some hints:
There are step and next instuctions (and also nexti and stepi).
(gdb) help next
Step program, proceeding through subroutine calls.
Usage: next [N]
Unlike "step", if the current source line calls a subroutine,
this command does not enter the subroutine, but instead steps over
the call, in effect treating it as a single source line.
So we can see that step steps into subroutines, but next will step over subroutines.
The step and stepi (and the next and nexti) are distinguishing by "line" or "instruction" increments.
step -- Step program until it reaches a different source line
stepi -- Step one instruction exactly
Related is finish:
(gdb) help finish
Execute until selected stack frame returns.
Usage: finish
Upon return, the value returned is printed and put in the value history.
A lot more useful information is at https://sourceware.org/gdb/onlinedocs/gdb/Continuing-and-Stepping.html
Use command 'finish'; this sometimes does the same thing as 'step-out'. It'll finish what the stack is doing (a function, usually), and go to the next line after that. Look up the command for more info.