访问旧堆栈帧 如果我理解这个正确,每次调用C++函数时,SP(和可能的BP)都会移动到堆栈上分配一些临时空间——堆栈帧。当函数返回时,指针被移回,再次释放堆栈帧

访问旧堆栈帧 如果我理解这个正确,每次调用C++函数时,SP(和可能的BP)都会移动到堆栈上分配一些临时空间——堆栈帧。当函数返回时,指针被移回,再次释放堆栈帧,c++,gdb,C++,Gdb,但在我看来,旧堆栈框架上的数据仍然存在,只是不再被引用。有没有办法让GDB显示这些删除的堆栈帧?(显然,一旦您输入一个新的堆栈帧,它将至少部分覆盖以前的堆栈帧……但在此之前,它似乎是可能的。)堆栈帧不包含任何关于其大小或边界的信息,而是将这些知识硬编码到函数的代码中。有一个(堆栈)帧指针寄存器,使用它可以向上移动堆栈,但不能向下移动。在当前函数中,您知道当前帧的边界,但是没有关于它下面可能有什么的信息 但在我看来,旧堆栈框架上的数据仍然存在,只是不再被引用 对 有没有办法让GDB显示这些删除的堆

但在我看来,旧堆栈框架上的数据仍然存在,只是不再被引用。有没有办法让GDB显示这些删除的堆栈帧?(显然,一旦您输入一个新的堆栈帧,它将至少部分覆盖以前的堆栈帧……但在此之前,它似乎是可能的。)

堆栈帧不包含任何关于其大小或边界的信息,而是将这些知识硬编码到函数的代码中。有一个(堆栈)帧指针寄存器,使用它可以向上移动堆栈,但不能向下移动。在当前函数中,您知道当前帧的边界,但是没有关于它下面可能有什么的信息

但在我看来,旧堆栈框架上的数据仍然存在,只是不再被引用

有没有办法让GDB显示这些删除的堆栈帧

您可以使用GDB
inspect
命令查看未使用的堆栈。例如:

void fn()
{
  int x[100];
  for (int j = 0; j < 100; j++) x[j] = (0x1234 << 12) + j;
}


int main()
{
  fn();
  return 0;
}
在这里您可以清楚地看到
x
仍然在堆栈上:
0x7fffffdc60
x[92]
过去的位置,
0x7fffffdc70
x[96]
过去的位置,等等


但要让GDB将该数据解释为
fn
的局部变量并不容易。

的确如此。您可以通过在子函数返回后查看调试器中的堆栈内存来验证这一点。但是,很难知道什么在哪里,因为您不再有匹配的堆栈和/或基指针。您确切地说“输入新堆栈帧”是什么意思?将堆栈指针更改为某个更高的帧本身不会删除您留下的帧中的数据,但您不必再次向下移动帧来删除旧帧-这可能是因为在上一帧中进行了操作(例如从调用的函数返回后分配1000字节的“堆栈内存”)。您不能扫描堆栈以查找与内存地址(其中包含代码)一致的64位数字吗?(即,可能是返回地址的数字。)
gcc -g t.c
gdb -q ./a.out

(gdb) start
Temporary breakpoint 1 at 0x115f: file t.c, line 10.
Starting program: /tmp/a.out 

Temporary breakpoint 1, main () at t.c:10
10    fn();
(gdb) n
11    return 0;
(gdb) x/40x $rsp-0x40
0x7fffffffdc60: 0x0123405c  0x0123405d  0x0123405e  0x0123405f
0x7fffffffdc70: 0x01234060  0x01234061  0x01234062  0x01234063
0x7fffffffdc80: 0x55555170  0x00005555  0x55555040  0x00000064
0x7fffffffdc90: 0xffffdca0  0x00007fff  0x55555169  0x00005555
0x7fffffffdca0: 0x55555170  0x00005555  0xf7a3a52b  0x00007fff
0x7fffffffdcb0: 0x00000000  0x00000000  0xffffdd88  0x00007fff
0x7fffffffdcc0: 0x00080000  0x00000001  0x5555515b  0x00005555
0x7fffffffdcd0: 0x00000000  0x00000000  0xa91c6994  0xc8f4292d
0x7fffffffdce0: 0x55555040  0x00005555  0xffffdd80  0x00007fff
0x7fffffffdcf0: 0x00000000  0x00000000  0x00000000  0x00000000