An Introduction To Using GDB Under Emacs

What is GDB?

GDB is a debugger. A debugger is a tool which can help you find bugs in your code. It will allow you to follow your program as it executes to see what happens at each step. The program can be stopped on any line or at the start of any function and various types of information can be displayed, such as the values of variables and the sequence of function calls that got you where you are. If your program causes a segmentation fault, GDB will show you where it happened. Advanced users can alter the values of variables to experiment with temporary bug fixes and view the contents of the stack.

The greatest advantage to using GDB within Emacs is that it will work with your source code (.c file). Whenever execution of the program is stopped (by a breakpoint, a segmentation fault, or some other signal), Emacs will display your source code in a window and will mark the line on which it has stopped with an => symbol. You can also use Emacs to cut and paste commands, scan through your GDB output and save it as a text file.

Where To Do This

This is for compiling and running programs on ssh onto grace using putty on a PC, or the 'ssh' command if using a linux box, a Mac, or Cygwin on a PC.

Starting GDB under Emacs

To run GDB in Emacs, first split your Emacs screen by typing `C-x 2' (C- stands for Control) and enter the window in which you want to run GDB by clicking in it with your left mouse button. Now type the command `M-x gdb' followed by `Return'. M- is read as Meta. On a Mac or PC, Meta is the Alt or Option key. M- is equivalent to ESC, except that you don't release Meta before pressing the next key, which makes it easier and faster than ESC.

The Emacs message bar will now display the message:
Run gdb (like this): gdb
Enter the name of your executable program. This is typically `a.out' unless you have renamed it (which any self-respecting programmer should).

Issuing Commands

The GDB window will display a message and then present you with the prompt (gdb). Whenever your cursor is on one of these prompts you can enter a GDB command. Pressing `Return' without entering a command will cause it to execute the previous command again. This is very convenient when stepping through a program line-by-line.

All GDB commands can be abbreviated unless doing so renders them ambiguous. Most of the commonly used commands can be abbreviated to one character. The following command descriptions are in the form: command (abbreviation) arguments. Arguments listed in brackets are optional.

help (h) [class][command]
With no arguments, this lists the command classes. If a class is specified, it will briefly describe commands in that class. If a command is specified, it will provide help on using that command.
quit (q)
Exit GDB. Type `C-x k' to kill the GDB buffer.

Loading and Running Programs

In order for GDB to be able to debug your program, you must compile the program with the `-g' option. Each time you recompile your program, you must reload it into GDB using the file command.
file file
Load a new executable file.
cd directory
If you start from within a directory different from the one containing your executable file, you will need to use this command to change to the proper directory.
run (r) [arglist]
This starts your program just as you would start it on the command line, except that `r' now replaces the name of your program. For example, if you normally run you program with `a.out 6 < inputfile > outputfile', you should run it under GDB with the command `r 6 < inputfile > outputfile'.
If your program is running, typing C-c twice will interrupt it and give you a GDB prompt. The program is only paused at this point and can be resumed with continue or destroyed with kill.
kill (k)
Terminate the program.

Moving Through the Program

GDB will normally run your program until completion, until you type `C-c C-c' or until the program asks for some input. In order to tell GDB to pause while running your program, you must set a breakpoint. Once the program has stopped, various commands will tell it how to proceed. More advanced users may want to experiment with watchpoints, although in general they are tricky to use and cause your program to run very slowly.
break (b) [function][line]
Set a breakpoint. If given a function name, GDB will break whenever that function is called. If given a line number, it will break whenever that line of your source code is reached.
C-x space
If you type this sequence while your cursor is in your source code, GDB will set a breakpoint at the line on which your cursor rests.
delete (d) n
Delete the breakpoint or watchpoint whose number is specified by n.
disable (dis) n
Temporarily disable the breakpoint or watchpoint whose number is specified by n.
enable (ena) n
Undo the effects of disable.
step (s)
step executes the next line of code. If the next line contains a function call, step will enter that function.
next (n)
next is similar to step except that it will step over function calls.
C-c  <
Equivalent to typing up.
C-c  >
Equivalent to typing up.
continue (c)
Resumes execution of the program until the next breakpoint is reached.
finish (fin)
Continue until the current function has returned.
until (u) [function][line]
Continue until the program reaches a source line greater than the current one. It can also be given an argument similar to break and will continue until the specified line or function is reached. until will also break upon returning from the current function.

Getting Information

print (p) expression
This command performs several functions. It is most commonly used to print out the value of a variable. It can be given any C expression, including casts. For example, `p (int) A->array[5]' will display the sixth element of the array specified by A->array as an integer. print will try to display its output in a nice format. If given a structure, it will show each field and value. If given a pointer to an array of characters, it will display the entire string.
If an assignment or function call is given to print, it will perform the operation and display the result. For example `p a = 5' will set the value of the variable a to 5. If `p f(4, a)' is then performed, it will execute the function f with the arguments 4 and 5 and will display the value returned by f.
info (i) [b]
Without a type specified, info will display a list of all info subcommands. `info b' will list all of the breakpoints and watchpoints you have set.
backtrace (bt)
Display the history of function calls leading up to the current line.

Quick Tour

  1. compile bugs as gcc -g -o bugs bugs.c
  2. in the same directory, start up emacs by typing emacs
  3. M-x gdb
  4. give gdb bugs in response to the "Run gdb (like this): " prompt. "-annotate=3" is fine if included in the prompt.
  5. Tell gdb to stop at the beginning of the program by typing b main)
  6. Set a breakpoint in foo by typing C-x o to get the cursor to the source window, using cursor characters to move the cursor over the "strlen()" call, then typing C-x space to set a breakpoint.
  7. Go back to the other window by again typing C-x o
  8. Continue by typing c.
  9. Display the stack backtrace by typing bt
  10. Go up by typing C-c < (note the little arrow moving)
  11. Go back down with C-c >
  12. Fix bug, save buffer, recompile, then cause to reload and start running again by just typting run.
  13. Use n and s to step or step over statements.
  14. Use p (or p/x for hex) to print out the results of several expressions.
  15. Change some variable or parameter values. For example, set var len=12 in dup216() to avoid the allocation bug (not large enough block).
  16. restart just by typing run again.
  17. ...repeat as needed...

Written by Doug Rohde, Modified by Pete Keleher.