4

我试图找出一种方法来使用 GDB 反向调试在程序中通过函数调用和变量副本来跟踪值的传播。我过去经常使用 GDB,但对反向调试相对较新。

我认为用一个例子来描述这个问题是最容易的。看看这个程序。

void FnA(int x) {
  printf("x=%d\n", x)
}

void FnB(int y) {
  int y_copy = y;
  FnA(y_copy);
}

void FnC(int z) {
  FnB(z);
}

int main() {
  int i;
  i = 5;
  FnC(i);
}

我编译程序,然后使用反向调试启动 GDB 以运行编译后的可执行文件。printf我在in处设置了一个断点FnA,然后让程序开始执行,这导致我命中了那个断点。从这里,我想回答“最后一次x写信到哪里?”这个问题。我可以做一个watch -l x然后reverse-continue。然而,这只会把我带到 的开头FnA,因为那是x它在堆栈上的生命周期开始的地方。我真正感兴趣的是i = 5一路回溯的赋值,main因为那是x's 价值的来源。从i = 5发生的那一刻起,真正的价值x只是通过函数参数和变量副本传播,如下所示:main:i -> FnC:z -> FnB:y -> FnB:y_copy -> FnA:x.

显然,我可以通过一些 GDB-fu 结合人类直觉来解决这个问题,但我正在努力使这个过程尽可能自动化。我最终想在更复杂的软件中尝试这个,使用人类直觉和 GDB-fu 会相当乏味。

有没有一种方便的方法可以通过反向调试在 GDB 中完成此任务?GDB 是否能够自动找出并遵循这些价值传播?

PS:具体来说,我实际上是在使用 GDB 和rr。rr 只是 gdb 的一个包装器,以允许确定性和可重现的执行上下文。我认为/希望核心问题保持不变,无论我是否使用带或不带 rr 的 gdb。

4

0 回答 0