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
import re
def print_stack_frame():
cur = gdb.selected_frame()
sp = int(cur.read_register("sp"))
info = gdb.execute("info frame", to_string=True)
match = re.search(r"Previous frame's sp is (0x[0-9a-fA-F]+)", info)
if not match:
print("Could not find previous frame's sp.")
else:
next_sp = int(match.group(1), 16)
count = (next_sp - sp) // 8
if count <= 0:
print("No valid stack range to display.")
else:
gdb.execute(f"x/{count}gx $sp")
class PrintStackFrame(gdb.Command):
def __init__(self):
super().__init__("print-stack-frame", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
print_stack_frame()
PrintStackFrame()
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 print_stack_frame.py
(gdb) print-stack-frame
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