Reputation: 4787
Are there any ways to see what values that are pushed onto the stack in a simple, preferably visual way? Currently I'm using gdb
for debugging, but was wondering if there were any other programs (or possibly even gdb in another mode) to have a view onto what the stack looks like as I step through each instruction, for example in this program:
.globl main
main:
push %rbp
mov %rsp, %rbp
movb $8, -1(%rbp)
movw $30, -4(%rbp)
mov -1(%rbp), %rax
add -4(%rbp), %rax
I know in gdb there is x/8xw $rbp
or variations thereof, but I'd like to view this almost like an animation or constant visualization while stepping through code. Is there a way to do that?
Upvotes: 1
Views: 1806
Reputation: 366066
There's display
to print something every time GDB stops, e.g.
display /x (long [8])*(long*)$rsp
to get output like this after every step. (This one from _start
, so RSP is pointing at argc
(0x1), then argv[0]
(a pointer), then argv[1]
(NULL), then envp[0]
, etc.)
{0x1, 0x7fffffffea02, 0x0, 0x7fffffffea0e, 0x7fffffffea1e, 0x7fffffffea6c, 0x7fffffffea7e, 0x7fffffffea92}
The GDB cast expression works by dereferencing $rsp
(the stack pointer) as a single long
, then casting that to an array of long
. This of course wouldn't actually work in C, but GDB expressions only use C-like syntax, they aren't proper C. There might be an easier way to write this, but it's what I came up with through trial and error.
This will show qwords in increasing order of memory address, starting with the one RSP points to, so it will change after a call
or push
, for example. If you want to see below RSP, into the red zone, use a different base, like ($rsp-16)
or something.
If you want a view of your function's stack frame below RBP that doesn't move with push/pop, you might want a base like ($rbp - 16)
or something.
Of course, your x/8xw $rbp
command doesn't show you any of the memory your instructions store into, because you're storing below RBP = RSP. (That's actually guaranteed safe in the x86-64 System V ABI, which has a red zone. In many other calling conventions, that could be stepped on asynchronously by a signal handler, or by a debugger evaluating print foo(1)
where foo
is a function in your program.)
Upvotes: 1