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) orsudo dnf install gdb(Fedora). - A C or C++ source file (e.g.,
program.c). - A compiler like
gccorg++(usually installed with the build-essential package).
Step-by-Step
- Compile with debug symbols. GDB needs symbol information to map machine code back to source lines. Compile with the
-gflag:
gcc -g -o program program.c(for C)
g++ -g -o program program.cpp(for C++) - Start GDB. Run
gdb ./program. You’ll see the GDB prompt(gdb). If your program needs command-line arguments, usegdb --args ./program arg1 arg2. - 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 mainorbreak my_function. - Run the program. Type
run(or justr). The program starts and stops at the first breakpoint. - Step through code. Use
next(orn) to execute the current line and move to the next, without entering functions. Usestep(ors) to step into a function call. Usecontinue(orc) to run until the next breakpoint or the end. - Inspect variables. Type
print variable_name(orp x) to see the current value. To watch a variable change, usewatch x— the program pauses whenxchanges. - Examine the call stack. When the program is paused, type
backtrace(orbt) to see the chain of function calls that led to the current line. This is invaluable for crash debugging. - List source code. Type
list(orl) to show the source around the current line. Uselist 20to show lines around line 20. - Quit GDB. Type
quit(orq). If the program is still running, GDB will ask for confirmation.
Common Mistakes
- Forgetting the
-gflag. Without debug symbols, GDB shows raw memory addresses and function names like??instead of source lines. - Using
nextwhen you meantstep. If you’re inside a function and want to go into a called function,nextskips over it. Usestepto enter. - Setting breakpoints after
run. Breakpoints must be set before the program reaches that line. If you set one afterrun, the program may have already passed it. - Typing
runagain after a crash. GDB returns to the prompt, but the program is still loaded. Just typerunagain to restart; don’t re-entergdb. - Using
printon an uninitialized variable. The value shown may be garbage — that’s often the bug itself, not a GDB error.
Tips
- Use
info breakpointsto list all breakpoints and their numbers. Delete one withdelete 2. - Conditional breakpoints save time:
break 15 if i == 100pauses only wheniequals 100. - Automate with a script. Put GDB commands in a file (e.g.,
commands.gdb) and rungdb -x commands.gdb ./program. - Use
display xto automatically printxafter every step. - For segfaults, just run — GDB will stop at the faulting line. Then type
btto see the call stack. - Use
set print pretty onto format structs and arrays in a readable, indented way.
Troubleshooting
- GDB says “No symbol table is loaded.” You compiled without
-g. Recompile with-gand reload the program withfile ./programinside GDB. - Breakpoint not hit. Check that the line number is correct (use
listto 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
ifthat’s false), it won’t trigger. Usebreak mainto start at the beginning. - GDB is slow or crashes. Very large programs can be slow. Try
set pagination offto 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/sourceinside GDB. - Error: “During startup program exited with code 127.” The program can’t find a shared library. Run
ldd ./programto check dependencies and setLD_LIBRARY_PATHif 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
- Google Chrome Helper: What It Is & How to Disable
- Fix 0x80070422 on Windows Server (Step-by-Step)
- How to Troubleshoot a Malfunctioning Driver on Windows
- How to Create Folders in Microsoft Outlook
- Fix Status Range List Conflict 0xc0000282 in Windows
- Fix Software Not Uninstalling on Windows 10