Debugging Assembly Code: When GDB Refuses to Show Your Variables
Debugging assembly code can feel like trying to solve a puzzle in a foreign language. While you might have the source code, it's the machine code that the debugger interacts with, and sometimes, that interaction can be frustrating. One common issue faced by developers is encountering an error message in GDB when trying to print a variable. This article explores why this occurs and how to overcome it.
The Scenario:
Let's imagine you're working on an assembly program and you want to check the value of a variable at a particular point in your code. You set a breakpoint, fire up GDB, and use the print
command:
# Sample assembly code (AT&T syntax)
.globl main
.data
my_var: .long 10
.text
main:
movl my_var, %eax
# ... (rest of your code)
# Breakpoint here
int $3
# GDB session
(gdb) break *main+10
Breakpoint 1 at 0x400510: file test.s, line 11.
(gdb) run
Starting program: /path/to/your/executable
...
Breakpoint 1, 0x400510 in main ()
(gdb) print my_var
$1 = 0x400508 <my_var>
Instead of showing the value of my_var
, GDB displays its memory address. Why?
Understanding the Issue
The key lies in the way GDB interacts with the assembly code. GDB doesn't inherently understand the symbolic names you use in your assembly code (my_var
in our example). It works with the machine code, which consists of instructions and memory addresses. When you ask GDB to print my_var
, it searches for a symbol named my_var
in its symbol table. Since this symbol is not defined in the machine code (as it's a symbol from the assembly source), GDB just returns the address where the variable is stored.
Solution: The Power of x
GDB provides a command specifically designed to inspect memory at a given address: x
.
(gdb) x/d my_var
0x400508: 10
This command instructs GDB to examine the memory location of my_var
(address 0x400508
) and display the value as a decimal number (d
for decimal).
Beyond the Basics: Advanced Debugging Tips
While the x
command is your go-to for variable inspection in assembly, you can further enhance your debugging experience:
- Choose the Right Format: GDB offers different formats for displaying memory contents. You can specify
x/x
for hexadecimal,x/c
for character,x/s
for string, and many more. - Set the Size: You can specify the size of the memory region you want to inspect. For example,
x/2wx
displays two words (4 bytes each) in hexadecimal. - Combine Commands: Combine
x
with other GDB commands likep
for printing expressions andc
for continuing execution.
Conclusion
While GDB might initially seem uncooperative when debugging assembly code, understanding how it interacts with machine code allows you to navigate the process effectively. By using the x
command and exploring its variations, you can gain valuable insights into your assembly program and troubleshoot issues with confidence.
Further Exploration
- GDB Manual: https://sourceware.org/gdb/current/onlinedocs/gdb.html
- Assembly Language Programming: Explore comprehensive resources for mastering assembly programming and debugging techniques.