Scenario
Application code
#include <cstdio>
int add(int n1, int n2)
{
int sum = n1 + n2;
printf("%d", sum);
return sum;
}
int main()
{
int n1 = 3;
int n2 = 8;
int sum = add(n1, n2);
printf("%d", sum);
return 0;
}
Print frame script
import gdb
class StackframePrinter(gdb.Command):
def __init__(self):
super().__init__("print-stackframe", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
cur = gdb.selected_frame()
try:
sp = int(cur.read_register("rsp"))
print(f"[Debug] Current SP: 0x{sp:x}")
except gdb.error as e:
print(f"[Error] Cannot read current SP: {e}")
return
prev_sp = None
caller = cur.older()
if caller:
saved = gdb.selected_frame()
try:
prev_sp = int(caller.read_register("rsp"))
print(f"[Debug] Caller SP: 0x{prev_sp:x}")
except gdb.error as e:
print(f"[Warn] Could not read caller SP: {e}")
if prev_sp and sp < prev_sp:
count = (prev_sp - sp) // 8
addr = sp
print(f"[Debug] Print {count} stack entries at 0x{addr:x}")
try:
gdb.execute(f"x/{count}gx {addr}")
except gdb.error as e:
print(f"[Error] Memory dump failed: {e}")
elif prev_sp == sp:
print("[Info] Frame optimized.")
else:
print("[Error] Corrupted stack.")
StackframePrinter()
Analysis
GDB session
$ lscpu | grep Arch
Architecture: x86_64
$ g++ -g main.cpp
$ gdb a.out
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git
...
(gdb) b 7
Breakpoint 1 at 0x1164: file main.cpp, line 7.
(gdb) r
Starting program: /home/max.sperling/Develop/test/a.out
Breakpoint 1, add (n1=3, n2=8) at main.cpp:7
7 return sum;
(gdb) info frame
Stack level 0, frame at 0x7fffffffe270:
rip = 0x555555555164 in add (main.cpp:7); saved rip = 0x55555555518e
called by frame at 0x7fffffffe290
source language c++.
Arglist at 0x7fffffffe260, args: n1=3, n2=8
Locals at 0x7fffffffe260, Previous frame's sp is 0x7fffffffe270
Saved registers:
rbp at 0x7fffffffe260, rip at 0x7fffffffe268
(gdb) info frame 1
Stack frame at 0x7fffffffe290:
rip = 0x55555555518e in main (main.cpp:14); saved rip = 0x7ffff7e01d7a
caller of frame at 0x7fffffffe270
source language c++.
Arglist at 0x7fffffffe280, args:
Locals at 0x7fffffffe280, Previous frame's sp is 0x7fffffffe290
Saved registers:
rbp at 0x7fffffffe280, rip at 0x7fffffffe288
(gdb) source stackframe_printer.py
(gdb) print-stackframe
[Debug] Current SP: 0x7fffffffe240
[Debug] Caller SP: 0x7fffffffe270
[Debug] Print 6 stack entries at 0x7fffffffe240
0x7fffffffe240: 0x0000555555554040 0x0000000300000008
0x7fffffffe250: 0x0000000000000000 0x0000000b00000000
0x7fffffffe260: 0x00007fffffffe280 0x000055555555518e
Frame 0
0x7fffffffe240: 0x0000555555554040 0x0000000300000008
0x7fffffffe250: 0x0000000000000000 0x0000000b00000000
0x7fffffffe260: 0x00007fffffffe280 0x000055555555518e
Unused preallocated uninitialized memory
Local Var 2
Local Var 1
Local Var 0
Caller RBP
Caller RIP