Reputation: 24872
When use gdb to debug assembly program, bt
will print the calling stack.
The questions are:
rbp
values stored in register for current function, and in stack for previous rbp values?rbp
value? (b-2) Is the mapping between stack base & function stored in executable file when -g
option is specified on compiling? (b-3) And how to read that mapping data, with readelf
? Which part?Upvotes: 2
Views: 1786
Reputation: 39551
Debuggers like GDB have two primary means of walking the stack in order to print a backtrace. They either assume the value in the frame pointer register (RBP) is a pointer to start of a linked list of stack frames, or they use special unwind info stored in the executable that describes how to walk (unwind) the stack.
When using the frame pointer, the assumption is that it points to where the current function saved the value of its caller's frame pointer. It also assumes that just before that saved frame pointer is where the return address for the current function is stored. So that's how it knows both what the RBP value of the calling function was, and what function called the current function, which it can easily determine from the return address. It can then find all the previous stack frames and functions on the stack by walking the linked RBP values.
However, this assumes that functions use the frame pointer this way, and generally there's no guarantee that they will. Basically it's assuming that the function prologue and epilogue looks something like this:
func:
push %rbp # save previous frame pointer
mov %rsp, %rbp # new frame pointer points to previous value
sub $24, %rsp # allocate stack space for this funciton
...
pop %rbp # restore previous frame pointer
ret
But when optimizing many compilers won't do this, because they rarely need to use a frame pointer and instead will treat RBP like any other general purpose register and use it for something else.
So to generate a backtrace across functions that don't use RBP as a frame pointer, a debugger can potentially use unwind information. This is special data stored in executables (and dynamic libraries) that describes exactly how to virtually undo all the stack operations performed by a function at any point in the execution of that function. The format and location of the unwind info varies based on the executable format and CPU type. For ELF x86-64 executables the unwind info is stored in the .eh_frame
section in a format based on the DWARF debugging format's unwind info. This format is too complex to describe here, but you can read the System V AMD64 ABI for more details.
Upvotes: 9