sodcalculator

10 Tech How-To

How to Use GDB in Linux: Step-by-Step Guide

Guide 10-26682 · Updated · Step by step

GDB (GNU Debugger) lets you pause a running program, inspect variables, step through code line by line, and find the exact line where a crash or bug occurs. This guide walks you through the essential commands to start debugging a C or C++ program from the Linux terminal.

What You’ll Need

  • A Linux system with GDB installed. Install it with sudo apt install gdb (Debian/Ubuntu) or sudo dnf install gdb (Fedora).
  • A C or C++ source file (e.g., program.c).
  • A compiler like gcc or g++ (usually installed with the build-essential package).

Step-by-Step

  1. Compile with debug symbols. GDB needs symbol information to map machine code back to source lines. Compile with the -g flag:
    gcc -g -o program program.c  (for C)
    g++ -g -o program program.cpp  (for C++)
  2. Start GDB. Run gdb ./program. You’ll see the GDB prompt (gdb). If your program needs command-line arguments, use gdb --args ./program arg1 arg2.
  3. Set a breakpoint. A breakpoint pauses execution at a specific line or function. To break at line 10: break 10. To break at a function: break main or break my_function.
  4. Run the program. Type run (or just r). The program starts and stops at the first breakpoint.
  5. Step through code. Use next (or n) to execute the current line and move to the next, without entering functions. Use step (or s) to step into a function call. Use continue (or c) to run until the next breakpoint or the end.
  6. Inspect variables. Type print variable_name (or p x) to see the current value. To watch a variable change, use watch x — the program pauses when x changes.
  7. Examine the call stack. When the program is paused, type backtrace (or bt) to see the chain of function calls that led to the current line. This is invaluable for crash debugging.
  8. List source code. Type list (or l) to show the source around the current line. Use list 20 to show lines around line 20.
  9. Quit GDB. Type quit (or q). If the program is still running, GDB will ask for confirmation.

Common Mistakes

  • Forgetting the -g flag. Without debug symbols, GDB shows raw memory addresses and function names like ?? instead of source lines.
  • Using next when you meant step. If you’re inside a function and want to go into a called function, next skips over it. Use step to enter.
  • Setting breakpoints after run. Breakpoints must be set before the program reaches that line. If you set one after run, the program may have already passed it.
  • Typing run again after a crash. GDB returns to the prompt, but the program is still loaded. Just type run again to restart; don’t re-enter gdb.
  • Using print on an uninitialized variable. The value shown may be garbage — that’s often the bug itself, not a GDB error.

Tips

  • Use info breakpoints to list all breakpoints and their numbers. Delete one with delete 2.
  • Conditional breakpoints save time: break 15 if i == 100 pauses only when i equals 100.
  • Automate with a script. Put GDB commands in a file (e.g., commands.gdb) and run gdb -x commands.gdb ./program.
  • Use display x to automatically print x after every step.
  • For segfaults, just run — GDB will stop at the faulting line. Then type bt to see the call stack.
  • Use set print pretty on to format structs and arrays in a readable, indented way.

Troubleshooting

  • GDB says “No symbol table is loaded.” You compiled without -g. Recompile with -g and reload the program with file ./program inside GDB.
  • Breakpoint not hit. Check that the line number is correct (use list to see the source). If you set a breakpoint on a function that is inlined or optimized out, it may not trigger. Compile with -O0 (no optimization) for reliable debugging.
  • Program runs but GDB doesn’t stop. If you set a breakpoint on a line that’s never executed (e.g., inside an if that’s false), it won’t trigger. Use break main to start at the beginning.
  • GDB is slow or crashes. Very large programs can be slow. Try set pagination off to avoid pausing output. If GDB itself crashes, update it (sudo apt update && sudo apt upgrade gdb).
  • Cannot see source code. GDB needs the source file in the same path as when compiled. If you moved the file, use directory /path/to/source inside GDB.
  • Error: “During startup program exited with code 127.” The program can’t find a shared library. Run ldd ./program to check dependencies and set LD_LIBRARY_PATH if needed.

Frequently Asked Questions

How do I debug a program that takes command-line arguments?

Start GDB with gdb --args ./program arg1 arg2, then type run. The arguments are passed automatically.

How do I inspect an array or a struct?

Type print array_name to see the whole array. For a struct, print struct_name shows all fields. To see a single element, use print array_name[3] or print struct_name.field.

What is the difference between next and step?

next executes the current line and stops at the next line, treating function calls as a single step. step enters the function and stops at its first line.

How do I debug a segfault?

Run the program in GDB with run. When it crashes, GDB stops at the faulting line. Type bt to see the call stack and identify which function caused the invalid memory access.

Can I change a variable’s value while debugging?

Yes. Use set variable x = 10 (or set x = 10) to change it, then continue running. This is useful for testing different paths without recompiling.

How do I debug a program that forks or runs multiple threads?

For forks, use set follow-fork-mode child to debug the child process. For threads, use info threads to list them, thread 2 to switch, and break file.c:line thread 2 to set a breakpoint for a specific thread.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →