As there are many tutorials can be found online, like this one and this example-based one, here I’m not going to list all usages or options of gdb, but just some techniques used during my debugs.
Program with command line arguments
For a code need supply command line arguments, the gdb debug command is
gdb --args executable arg1 arg2 ... argn
For example, an executable code named foo takes a file input as argument (contains all parameters needed by foo),
gdb --args foo input
Debugging a crashed program
When your program is crashed, a segmentation fault, for example. Using the core dump will be very helpful in locating the causes. The basic steps are,
- type ulimit -c unlimited in an xterm (this allows the creation of core/postmorterm files)
- launch your program (and let it crash): a core file should now be present in the directory
- launch the debugger with gdb yourprogram corefile or gdb –args yourprogram arg1 arg2 arg3 to run gdb with parameters
- type bt at gdb prompt to see on what line it did crash
- type frame framenumber to select a particular frame, and get more info
- use list to show the code around this frame, and info locals to see the local variables and print variable to show its value
Here is an example,
(bash) ulimit -c unlimited
(bash) Soft2D input
(bash) gdb Soft2d core
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `Soft2D input'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __GI___libc_free (mem=0x3fd00e6251f20673) at malloc.c:2951
2951 malloc.c: No such file or directory.
[Current thread is 1 (Thread 0x7f09e39357c0 (LWP 1057))]
(gdb) bt
#0 __GI___libc_free (mem=0x3fd00e6251f20673) at malloc.c:2951
#1 0x0000000000408f87 in myarray<double>::~myarray (this=0x7ffe173923f0, __in_chrg=<optimized out>) at src/../include/myarray.h:240
#2 0x00000000004081a1 in geometry::computeCurvesGeoProperties (this=0x651888 <run_input+136>) at src/geometry.cpp:179
#3 0x0000000000403ea6 in input::setup (this=0x651800 <run_input>, fileNameC=0x7ffe17394f84 "input") at src/input.cpp:107
#4 0x0000000000402be2 in main (argc=2, argv=0x7ffe17392d08) at src/main.cpp:45
(gdb) fram 1
#1 0x0000000000408f87 in myarray<double>::~myarray (this=0x7ffe173923f0, __in_chrg=<optimized out>) at src/../include/myarray.h:240
240 delete[] cpu_data;
(gdb) list
235 // destructor
236
237 template <typename T>
238 myarray<T>::~myarray()
239 {
240 delete[] cpu_data;
241 // do we need to deallocate gpu memory here as well?
242 }
243
244 // #### methods ####
(gdb) print cpu_data
$1 = (double *) 0x3fd00e6251f20673
Setting breakpoints
Breakpoints are set with the break command (abbreviated b). Here are several ways to say where the breakpoint should go.
# Set a breakpoint at entry to function function.
break function
# Set a breakpoint some number of lines forward or back from the position at which execution stopped in the currently selected stack frame
break +offset
break -offset
# Set a breakpoint at line linenum in the current source file.
break linenum
# Set a breakpoint at line linenum in source file filename.
break filename:linenum
# Set a breakpoint at entry to function function found in file filename.
break filename:function
# Set a breakpoint at address address. You can use this to set breakpoints in parts of your program which do not have debugging information or source files.
break *address
# Print a table of all breakpoints, watchpoints, and catchpoints set and not deleted
info breakpoints [n]
info break [n]
info watchpoints [n]
Another way to start
- Compile your application with -g, then you’ll have debug symbols in the binary file.
- Use gdb to open the gdb console.
- Use file and pass it your application’s binary file in the console.
- Use run and pass in any arguments your application needs to start.
- Do something to cause a Segmentation Fault.
- Type bt in the gdb console to get a stack trace of the Segmentation Fault.