Advance debugging C/C++ code in GDB in Linux

The purpose of a debugger is to allow us to see what is going on inside our C/C++ program while it runs. In addition, we can use gdb to see what our program was doing at the moment it crashed.
Task that gdb can perform:
Start your program and step through it line by line
  • Make your program stop on specified conditions
  • Show the values of variables used by your program
  • Examine the contents of any frame on the call stack
  • Set breakpoints that will stop your program when it reaches a certain point. Then you can step through part of the execution using step and next,
  • and type continue to resume regular execution.
  • For C and C++ programs, gdb and ddd are debuggers that you can use. ddd is a easy-to-use GUI wrapper around an inferior debugger (gdb for GNU
  • compiled C or C++ code). ddd allows you to interact with the debugger by using either GUI menu options or the under-lying debugger's command line
  • interface. In addition, ddd automatically displays source code when breakpoints are reached.
Commonly used gdb commands
  • gdb also understands abreviations of commands, so you can just type up to
  • the unique part of a command name ("cont" for "continue", or "p" for "print")
  • help # List classes of all gdb commands
  • help <topic> # Shows help available for topic or command
  • where (or bt) # Shows stack: sequence of function calls executed so far
  • # (good for pinpointing location of a program crash)
  • frame # Shows all stack frames
  • frame <frame-num> # Sets current stack frame to <frame-num>
  • # (useful for checking parameter and argument values)
  • run # Starts program execution from the beginning
  • break <line> # Sets breakpoint at line number <line>
  • break <func-name> # Sets breakpoint at beginning of named function
  • continue # Continues execution from breakpoint
  • condition <bp-num> <exp> # Set breakpoint <bp-num> to
  • # break only when <exp> is true
  • info break # Shows current breakpoints
  • disable [breakpoints] # [bnums ...] Disable one or more breakpoints
  • enable [breakpoints] # [bnums ...] Enable one or more breakpoints
  • clear <line> # Clears breakpoint at line number <line>
  • delete <bp-num> # Deletes breakpoint number <bp-num>
  • delete # Deletes all breakpoints
  • step (or s) # Executes next line of program (steping into functions)
  • step <count> # Executes next <count> lines of program
  • next (or n) # Like step, but treats a function call as a single instr
  • until <line> # Executes program until line number <line>
  • print <exp> (or inspect <exp> # Displays the value of expression <exp>
  • display <exp> # Automatic display of <exp> each time a breakpt hit
  • whatis <exp> # Shows data type of expression <exp>
  • info locals # Shows local variables in current stack frame
  • set variable <variable> = <exp> # Sets variable <variable> to expression <exp>
  • list # Lists next few lines of program
  • list <line> # Lists lines around line number <line> of program
  • list <start> <end> # Lists line numbers <start> through <end>
  • list <func-name> # Lists lines at beginning of function <func-name>
  • help status # lists a bunch of info X commands, including:
  • info frame # list information about the current stack frame
  • info locals # list local variable values of current stack frame
  • info args # list argument values of current stack frame
  • info registers # list register values
  • quit # quits gdb
Compile, run, attach to running program:
(1) always compile .o and executable files with -g
% gcc -g -o myprog main.c
 of course you should always use a Makefile and add -g to the build rules 
or for cs21 if you compile with the gccx compiler it automatically 
inculdes the -g flag for you

(2) to start a program in the debugger
% gdb ./a.out
% ddd ./a.out   # ddd is the GUI interface to gdb
you will get the gdb prompt before it starts executing myprog code
you can add breakpoints here, then start program running
(gdb) run
OR if myprog has command line arguments
(gdb) run arg1 arg2 ... argn

(3) to attach gdb to an already running program
(a) get the process id, pid, for the program
for example, to get the pid of my infiniteloop process:
% ls
15586 pts/15   00:00:00 tcsh
29390 pts/15   00:00:01 infiniteloop
(b) attach gdb to it 
Two was: 
(1) start new gdb specifying pid 
gdb executable name <pid>
$ gdb infiniteloop  29390 
 (2) from within gdb use attach command
attach <pid>
$ gdb infiniteloop
(gdb) attach 29390 

No comments:

Post a Comment