调试:是不是可以在不进入每个堆栈帧的情况下打印 C 代码的所有局部变量(带有值)?

Posted

技术标签:

【中文标题】调试:是不是可以在不进入每个堆栈帧的情况下打印 C 代码的所有局部变量(带有值)?【英文标题】:Debugging : is it possible to print all local variable (with values) of C code without going into each stack frame?调试:是否可以在不进入每个堆栈帧的情况下打印 C 代码的所有局部变量(带有值)? 【发布时间】:2013-05-14 09:34:58 【问题描述】:

我正在尝试探索gdbobjdumpvalgrindnm 用于在 linux 中进行调试的工具。

我可以在 GDB 中使用 info locals 打印局部变量,但我需要进入当前堆栈帧才能打印局部变量。

有没有什么方法可以在不进入特定堆栈帧的情况下打印 C 代码中使用的所有局部和全局变量(带有值)(如果程序崩溃,可能来自 coredump)?

【问题讨论】:

"info variables"----> 打印在函数之外声明的所有变量的名称和数据类型(即不包括局部变量)。但是你不会得到值。 "info locals"---> 打印所选框架的局部变量,每个变量都在单独的行上。这些都是在所选框架的执行点可访问的所有变量(声明为静态或自动)。同样你不会得到值。它只是列表 【参考方案1】:

正如您所指出的,在gdb 中,您可以使用info locals 显示当前帧的局部变量。如果您的限制是您不想手动进入每个帧,那么您可以使用一个简单的gdb 脚本来为您执行此操作。例如:

define locals-up
  set $n    = ($arg0)
  set $upto = $n
  while $upto > 0
    info locals
    up-silently 1                                                                
    set $upto = $upto - 1
  end
  down-silently $n
end
document locals-up
  locals-up <n>: Lists local variables of n frames
end

【讨论】:

【参考方案2】:

不,因为您必须分析堆栈才能找出甚至存在哪些局部变量。

如果你有一个函数:

static int foo(int a, int b, int c)

  const int ab = a + b;
  const int bc = b + c;

  return ab * bc;

你不能谈论“foo() 的局部变量”,除非你有一个堆栈帧表明foo() 正在运行。否则,局部变量将不存在:毕竟,它们是在进入函数时在堆栈上分配的。

当然,可能有一个“聪明”的命令可以从给定断点的帧向上遍历堆栈并打印所有遇到的函数的局部变量,但这听起来不像你想要的。

【讨论】:

正如您所说,在输入函数时,局部变量会在堆栈上分配。所以没有办法将带有值的局部变量(在执行函数时)保存在文件中。这对于调试很有用。 我不知道有任何调试器可以“自动”执行此操作。可能会很混乱,尤其是从多个线程输入函数时。

以上是关于调试:是不是可以在不进入每个堆栈帧的情况下打印 C 代码的所有局部变量(带有值)?的主要内容,如果未能解决你的问题,请参考以下文章

Android下打印调试堆栈方法(转)

有没有办法在不抛出异常的情况下转储堆栈跟踪?

手机调试Android程序出异常时不打印堆栈信息

如何测量 C 中的函数堆栈使用情况?

如何实现一个系统调用,它可以在不进入内核日志的情况下检查自身是不是已成功执行?

在不改变链表的情况下从尾到头打印连表