thecodex.expert · The Codex Family of Knowledge
C

Debugging with GDB

A segfault by itself tells you almost nothing — not which line, not which pointer, not why. GDB is how you actually find out.

C17 / C23 Compile with -g first Last verified:
Canonical Definition

GDB runs a compiled executable under its control, allowing breakpoints (pausing execution at a specific line), stepping through code one line or one function call at a time, and inspecting variable values and the call stack at any paused point. This matters especially in C because the language itself gives almost no runtime diagnostic information — a segfault just terminates the program with no line number, no stack trace, and no explanation, unless a debugger was attached to capture that moment. The -g compiler flag is required beforehand, embedding the debug symbols GDB needs to map machine code back to source lines and variable names.

Compiling with debug symbols and starting GDB

Without -g, the executable still runs identically, but GDB has no way to connect machine instructions back to your original source lines or variable names — it would only show raw addresses and registers.

Cterminal
$ gcc -g -Wall -o myapp main.c   // -g embeds debug symbols
$ gdb ./myapp
(gdb) run                          // starts the program under GDB's control

Breakpoints and stepping

next steps over a function call (running it to completion without descending into it); step descends INTO the called function — the distinction matters when you want to skip past code you already trust is correct.

Cgdb session
(gdb) break main         // set a breakpoint at the start of main()
(gdb) break 25             // or at a specific line number
(gdb) run
(gdb) next                  // execute the next line, stepping OVER function calls
(gdb) step                   // execute the next line, stepping INTO function calls
(gdb) print x               // inspect a variable's current value
(gdb) continue              // resume running until the next breakpoint

Post-mortem debugging: finding a crash after the fact

backtrace is often the single most useful GDB command for a real crash — it shows the exact chain of function calls that led to the failure, which is precisely the information a bare segfault message never provides on its own.

Cgdb session
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555169 in processData (data=0x0) at main.c:15
15          return data->value;   // data was NULL — now we know exactly where and why

(gdb) backtrace              // shows the full call chain that led here
#0  processData (data=0x0) at main.c:15
#1  main () at main.c:22

Sources

1
Free Software Foundation. Debugging with GDB, sourceware.org/gdb/current/onlinedocs/gdb.