Lecture 30 - Debugging with GDB

Published

April 27, 2026

Goals

  • learn the basics of working with gdb the GNU Debugger

Using GDB

One of our primary tools for debugging is print statements, but they are limited

  • they are just a snapshot – if we want to see values change we have to write a ton of print statements and then wade through them
  • if we realize there is something else it would be good to know we need to add more print statements and run the code again
  • they clutter our code

The debugger is a much more powerful forensic tool for finding problems.

  • We can operate on live code
  • we can set variables to be displayed after every step
  • we can poke around in memory in the middle of a program’s execution
  • we can establish breakpoints at critical points in the code
  • etc

We will be looking at the GNU Debugger (gdb)

When debugging, we want to compile the code with two new flags

  • -g - This flag adds the original source code into the executable so the debugger can show us the code that is being executed in C (generally easier than looking at the assembly…). Just make sure you don’t leave -g on for production code – it makes your code slow and bloated.
  • -O0 - That is a capital letter ‘O’ and zero. That turns off all compiler optimization. The compiler can make all kinds of optimizations in our code, including eliminating loops and whole functions. This can make for a very confusing experience when we are stepping through the original C code

basic commands

  • run args
    • short name r
    • start the program and pass it args
  • break function name | line number (condition)
    • short name b
    • sets a breakpoint in the code at the function or line number. Code execution will pause when it reaches the breakpoint
    • the condition can look at variable values to determine when to stop
    • remove a breakpoint with clear breakpoint
    • can use info break to find current breakpoints
  • continue
    • short name c
    • restarts execution after a break
  • next
    • short name n
    • goes to the next line, stepping over function calls
  • step
    • short name s
    • goes to the next line, entering any function calls
  • print [/f] expression
    • short name p
    • expression is any C expression that returns a value
    • the /f is an optional formatting flag (/x will display in hex)
    • many other options, but that we be enough for us
  • display expression
    • works the same as print, but repeats after each line
    • turn off with undisplay n
  • examine [/Nuf] expression
    • short name x
    • allows us to inspect memory at the address that expression resolves to
    • N is the number of elements
    • u the size ((b)yte, (h)alfword, (w)ord, (g)iant)
    • f, format (same as print)
  • list (line number | function )
    • shows the lines of code around the specified line, function or where we are if nothing else is specified
  • backtrace
    • short name bt
    • show the call stack
  • help command
    • we can ask for help for about anything
    • apropos can be used if we can’t remember the exact name of a command
  • info
    • query the state of the program or our session
    • some options
      • break - show the active breakpoints
      • reg register - show the register state
      • locals - show all of the local variables

example

simple function

We can start by looking in the code we wrote for lecture 24

int sum(int x, int y){
  int result;
  result = x + y;
  return result;

}


int main(int argc, char * argv[]){
  int a,b,c;
  a = 1;
  b = 2;
  c = sum(a,b);
}

compile for debugging and start gdb

$ gcc -g -O0 -o func1 func1.c
$ gdb func1

look at the available functions (this will also print out functions not in the code)

(gdb) info functions
All defined functions:

File func1.c:
10:     int main(int, char **);
2:      int sum(int, int);

set a breakpoint

(gdb) b sum
Breakpoint 1 at 0x401110: file func1.c, line 4.

run the program (I trimmed out the part about debuginfo)

(gdb) r
Starting program: /home/candrews/cs202/s23/debugging/func1

Breakpoint 1, sum (x=1, y=2) at func1.c:4
4         result = x + y;

look at the original source

(gdb) list
1
2       int sum(int x, int y){
3         int result;
4         result = x + y;
5         return result;
6
7       }
8
9
10      int main(int argc, char * argv[]){

broken float

I have a program that prints out all of the floats we can get with an eight bit number. When we run it, the output looks a little strange. The negative numbers are all really big compared to the positive numbers. They should be symmetric.

When we return next time, we will dive into the debugger and see if we can figure out why…

Mechanical level

vocabulary

Skills