This diagram from the Wikipedia article Call stack may help: 
GDB's info frame
corresponds to functions being called in your program at run time. From the output, we can infer this about the stack frame layout:
- 0xb75f7388: The 4 bytes starting here stores the old EBP value, 0xb75f73a8. The first value pushed by the function prologue of
base::func()
- 0xb75f738c: The 4 bytes starting here stores the return address, 0x804869a. Pushed by the
call
instruction in the previous frame
- 0xb75f7390: The 4 bytes starting here stores the implicit
this
argument to base::func()
, 0x00000000.
I'll explain the info frame
output line by line:
Stack level 0, frame at 0xb75f7390:
Stack level 0 means this is the newest frame. The address after frame at
is called the Canonical Frame Address (CFA). On x86, this is defined to be the value of the stack pointer (ESP) at the previous frame, before the call instruction is executed.
eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
EIP is the x86 instruction pointer. saved eip
is the return address.
If you try to look up the function that contains 0x804869a with info symbol 0x804869a
, it should point inside the function calling base::func()
.
called by frame at 0xb75f73b0
called by
shows the canonical frame address of the previous frame. We can see that the stack pointer advanced 32 bytes (0xb75f73b0 - 0xb75f7390 = 32) between the two frames.
source language c++.
Arglist at 0xb75f7388, args: this=0x0
Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
The x86 ABI passes arguments on the stack. base::func()
only has the single implicit this
argument. The fact that it's 0x0
i.e. NULL
bodes ill. On a side note, Arglist
and Locals
seem to always have the same value in info frame
on x86 and x86-64.
Saved registers:
ebp at 0xb75f7388, eip at 0xb75f738c
Saved registers
reflects the registers that were saved at function entry. It lists where the old register values are saved on the stack. Saved EIP is the return address so if you examine the address stored at 0xb75f738c with x/a 0xb75f738c
it should give 0x804869a. The fact that EBP is listed here implies that your code probably was not compiled with -fomit-frame-pointer
and has a standard function prologue:
push %ebp
movl %esp, %ebp
at the very begging of base::func()
which sets up EBP to act as the frame pointer.