Debugging Souce Code with Assembly
If we compile C program with -g flag, it tells GCC to include debugging symbols inside the resulting binary (a.out by default). These symbols live in a special section of the ELF file (like .debug_info, .debug_line, .debug_str, etc.) and contain metadata that maps machine instructions back to your original source code.
This allows us to see corresponding source along with assembly while debugging with GDB.
Let’s take this program
// firstprog.c
#include<stdio.h>
int main()
{
int i;
for (i=0; i<10; i++) {
printf("Hello, World!\n");
}
}
sanketh@sanketh-81de:~/assembly/gdb$ gcc -g firstprog.c
sanketh@sanketh-81de:~/assembly/gdb$ readelf -S a.out | grep debug
[28] .debug_aranges PROGBITS 0000000000000000 0000303b
[29] .debug_info PROGBITS 0000000000000000 0000306b
[30] .debug_abbrev PROGBITS 0000000000000000 00003105
[31] .debug_line PROGBITS 0000000000000000 00003159
[32] .debug_str PROGBITS 0000000000000000 000031bc
[33] .debug_line_str PROGBITS 0000000000000000 00003295
We can see the source code using list command
(-q flag just tells gdb not to print version and some info on startup)
$ gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) list
1 #include<stdio.h>
2
3 int main()
4 {
5 int i;
6 for (i=0; i<10; i++) {
7 printf("Hello, World!\n");
8 }
9 }
You can even control the detail level: • -g1: minimal info (function names, line numbers) • -g2: normal (default) — enough for GDB • -g3: adds macro
We can also
gcc -g -O0 -Wall -o prog prog.c
-0O means no optimizations, which will prevent reordering of instructions. Because optimization (-O2, -O3) can reorder or remove variables, making debugging confusing.
GDB Layouts
GDB has a Text User Interface (TUI) mode that lets you see source code, assembly, and registers in split or full-screen views.
It’s very useful when stepping line-by-line or instruction-by-instruction.
You enter TUI mode using:
(gdb) layout [mode]
Available Layouts
| Command | View | Description |
|---|---|---|
layout src | Source view | Shows only C source lines (if compiled with -g) |
layout asm | Assembly view | Shows disassembly around current instruction |
layout split | Split view | Shows both source + assembly side by side |
layout regs | Registers view | Shows CPU registers (RAX, RBP, etc.) |
layout next | Cycle layouts | Switch to the next available layout (GDB switches to the next view mode in this order: src → asm → split → regs → src → …) |
GDB Navigation & Stepping Commands
1. Source-Level (C) Navigation
These commands work on C source lines when the binary is compiled with -g.
| Command | Short | Meaning | Steps Into? | Description |
|---|---|---|---|---|
next | n | Next line | ❌ No | Executes the next C line, skipping over function calls. |
step | s | Step into | ✅ Yes | Executes the next C line, enters called functions. |
finish | — | Finish current function | — | Runs until the current function returns. |
continue | c | Continue execution | — | Runs until next breakpoint or program exit. |
until | u | Run until a specific line | — | Continue until a specific line number or loop ends. |
2. Assembly-Level Navigation
These work on individual machine instructions, not source lines.
Ideal for reverse engineering or checking compiler output.
| Command | Short | Meaning | Steps Into? | Description |
|---|---|---|---|---|
nexti | ni | Next instruction | ❌ No | Execute one assembly instruction, skip over calls. |
stepi | si | Step instruction | ✅ Yes | Execute one instruction, enters called functions. |
until | u | Until address | — | Run until a specified instruction address. |
3. Breakpoints & Execution Flow
| Command | Short | Description |
|---|---|---|
break <line/function> | b | Set a breakpoint. Example: b main or b 12. |
info breakpoints | info b | List all breakpoints. |
delete <num> | d | Remove a breakpoint. |
disable / enable | — | Temporarily turn breakpoints off/on. |
run | r | Start program execution. |
continue | c | Resume execution after breakpoint. |
finish | — | Run until current function returns. |
kill | — | Stop the program being debugged. |
quit | q | Exit GDB. |
4. Viewing Context While Navigating
| Command | Description |
|---|---|
list or l | Show source lines around current location. |
layout src | Show C source view (TUI). |
layout asm | Show disassembly view. |
layout split | Show both C and assembly views. |
info registers | Show CPU registers. |
x/i $pc | Show current instruction. |
disassemble /s | Show mixed C and assembly view. |