【问题标题】:Access old stack frames访问旧堆栈帧
【发布时间】:2019-09-25 10:33:56
【问题描述】:

如果我的理解是正确的,那么每次调用 C++ 函数时,SP(可能还有 BP)都会移动以在堆栈上分配一些临时空间——堆栈帧。当函数返回时,指针被移回,再次释放堆栈帧。

但在我看来,旧堆栈帧上的数据仍然存在,只是不再被引用。有什么方法可以让 GDB 向我展示这些已删除的堆栈帧吗? (很明显,一旦你进入一个 new 堆栈帧,它至少会部分覆盖任何以前的堆栈帧......但在那之前它似乎应该是可能的。)

【问题讨论】:

  • 确实如此。您可以通过在从子函数返回后查看调试器中的堆栈内存来验证这一点。但是,很难知道什么在哪里,因为您不再有匹配的堆栈和/或基指针。
  • “进入一个新的堆栈帧”到底是什么意思?将堆栈指针更改为更高的帧本身不会破坏您离开的帧中的数据,但是您不必再次向下帧以使旧帧被破坏 - 这可能是由于操作而发生的上层帧(如被调用函数返回后分配1000字节的“栈内存”)。
  • 您不能扫描堆栈以查找与其中包含代码的内存地址一致的 64 位数字吗? (即,可能是返回地址的数字。)

标签: c++ gdb


【解决方案1】:

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

正确。

有什么方法可以让 GDB 显示这些已删除的堆栈帧吗?

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

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


int main()
{
  fn();
  return 0;
}

构建和调试:

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

在这里您可以清楚地看到x 仍在堆栈中:0x7fffffffdc60x[92] 曾经所在的位置,0x7fffffffdc70x[96] 曾经所在的位置,等等。

虽然没有简单的方法让 GDB 解释该数据为 fn 的本地数据。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-17
      • 2011-03-22
      • 1970-01-01
      • 2016-01-12
      • 2015-11-07
      • 2016-04-11
      • 2018-03-17
      • 2020-03-20
      相关资源
      最近更新 更多