获取当前作用域中定义的所有变量

3
此问题已经被其他语言问过:PythonPHPJavaScript。我想知道在C中是否可能做到这一点。我正在尝试在执行过程中的某个时间点获取函数中所有变量的快照,然后将其与稍后的另一个快照进行比较。
编辑: 快照可以是范围内所有变量及其当前值的列表。我可以手动编码,但我想知道是否有更快的方法。

“获取快照”是什么意思?让程序显示它们?还是让调试器显示它们? - wallyk
3
可能是 如何在 C 语言中获取堆栈跟踪? 的重复问题。 - Brian Roach
4个回答

10

是和否

是否有语言特性?没有。

能以独立于系统的方式完成吗?不行。

有简单的方法吗?没有。

能以某些努力的系统特定方式完成吗?可以。

总之,没有好的方法也没有简单的方法,但如果你真的非常想做到,它是可行的。广义上讲,程序被编译为调试模式,然后在运行时打开映像文件并找出哪些变量存在以及它们存储在哪里。最可能实现这个任务的实用方法将是编写一个像gdb这样的调试器脚本,让它执行低级工作。

如果您的系统已经具有运行时回溯功能,那么您可能可以利用该功能。

另一种可能性:一些操作系统支持读取符号表的库函数。历史悠久的Unix和Mac OS X具有nlist(3)。 一些版本的Linux和Solaris具有dlinfo(3)。 一个名为nm(1)的CLI工具(您可以通过popen(1)使用它)通常是可用的。


实际上,一个人可以使用“穷人的分析器”作为起点。 - dmckee --- ex-moderator kitten

0

根据您感兴趣的C程序,您可以使用Frama-C,特别是完全展开的value analysis,来模拟执行,然后插入调用Frama_C_dump_each()以获取程序特定点上变量值的转储。

您可以期望完全展开的分析模拟执行比实际执行慢10000到100000倍,但现在我们有快速计算机。这仍然只适用于相对较小的程序。

例如:

int x,a;
int y=2;

void f(void)
{
  int lf = 5;
  a = y + 2;
  Frama_C_dump_each();
  return;
}

main(){
  int lmain = 3;
  f();
  return 0;
}

$ frama-c -val -slevel 50000 t.c
....
[value] DUMPING STATE of file t.c line 8
    x ∈ {0; }
    a ∈ {4; }
    y ∈ {2; }
    lf ∈ {5; }
    lmain ∈ {3; }
    =END OF DUMP==
....

0

在一个如此低级的(编译)语言中,你根本无法做到这一点。当编译器+链接器完成你的代码后,几乎没有“变量”的痕迹,只有原始的机器码。


@Carl Norum:它使用特别注入的代码。解释性语言(通常)不需要调试符号来实现这一点。 - nc3b
1
关于需要调试符号,那是无关紧要的。他在问你如何做到这一点,这将是其中的一部分。 - Brian Roach
2
@Brian Roach:好的,我确实不知道backtrace(3)。你怎么列出变量和值 - nc3b
好的,你已经有了堆栈帧...所以你从那里开始。我并没有说这很容易,但说它不可能是错误的。gdb并不是魔法。 - Brian Roach
2
这不是魔法,而是使用调试符号。这不是生产程序中可用的东西,我觉得也不是问题所在。这与“容易”和“困难”无关。一个正常的二进制文件将完全没有标识符名称的任何迹象。 - nc3b
显示剩余3条评论

0

这并不简单。你需要在二进制级别上做这样的事情,并且了解编译器将数据结构放置在硬件中基指针的位置。你还需要调试符号。

简短的答案是否定的,没有付出相当大的努力是不可能实现的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接