24

我们如何列出应用程序中调用的所有函数。我尝试使用 GDB,但它的回溯列表只到主函数调用。

我需要更深入的列表,即主函数调用的所有函数的列表以及从这些被调用函数调用的函数等等。

有没有办法在 gdb 中得到这个?或者你能给我一些关于如何得到这个的建议吗?

4

4 回答 4

25

我们如何列出应用程序中调用的所有函数

对于任何实际大小的应用程序,此列表将包含数千个条目,这可能会使其无用。

您可以使用命令找出应用程序中定义(但不一定调用)的所有函数nm,例如

nm /path/to/a.out | egrep ' [TW] '

您还可以使用 GDB 在每个函数上设置断点:

(gdb) set logging on     # collect trace in gdb.txt
(gdb) set confirm off    # you wouldn't want to confirm every one of them
(gdb) rbreak .           # set a breakpoint on each function

一旦你继续,你会为每个调用的函数打一个断点。使用disableandcontinue命令前进。我不相信有一种简单的方法可以实现自动化,除非你想使用 Python 脚本。

已经提到gprof的是另一个不错的选择。

于 2012-03-03T20:58:52.327 回答
10

你想要一个调用图。您要使用的工具不是 gdb,而是gprof. 你编译你的程序,-pg然后运行它。gmon.out运行时会生成一个文件。然后,您处理此文件gprof并享受输出。

于 2012-03-03T20:47:57.307 回答
9

记录函数调用历史

https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html

如果您是少数拥有支持Intel 处理器跟踪(Intel PT,in )的 CPU 的人之一(2015 年),这应该是一个很好的硬件加速可能性。intel_pt/proc/cpuinfo

GDB 文档声称它可以产生如下输出:

(gdb) list 1, 10
1   void foo (void)
2   {
3   }
4
5   void bar (void)
6   {
7     ...
8     foo ();
9     ...
10  }
(gdb) record function-call-history /ilc
1  bar     inst 1,4     at foo.c:6,8
2    foo   inst 5,10    at foo.c:2,3
3  bar     inst 11,13   at foo.c:9,10

在使用它之前,您需要运行:

start
record btrace

这是一个无能力的 CPU 失败的地方:

 Target does not support branch tracing.

CPU 支持进一步讨论:如何在 GDB 中运行记录指令历史和函数调用历史?

相关话题:

对于嵌入式,您还可以考虑 JTAG 和支持硬件,如 ARM 的DSTREAM,但 x86 支持似乎不是很好:使用硬件调试器调试 x86 内核

于 2015-08-04T16:26:53.570 回答
3

这个问题可能需要澄清,以决定目前有 2 个答案。取决于你需要什么:

1)您需要知道每个函数以与调用次数匹配的函数的直接列表/图形格式被调用多少次。如果您的代码不是程序化的(即函数调用分支结构中的其他函数,而没有明确调用什么),这可能会导致模棱两可/不确定的结果。这是基本的 gprof 功能,需要使用 -pg 标志重新编译。

2)您需要按调用顺序列出函数,这取决于您的程序,这是最佳/可行的选择:a)如果您的程序运行并终止而没有运行时错误,您可以为此目的使用 gprof。b) 上面使用带有日志记录和断点的 dbg 的 ELSE 选项是我在阅读本文时学到的剩余选项。

3) 您不仅需要知道顺序,还需要知道例如每次调用的函数参数。我目前的工作是模拟粒子传输的物理学,所以这对于追踪异常结果的来源绝对有用......即当参数被传递时不再有意义。我想这样做的一种方法是对 Employed Russian 所做的改变,除了使用以下内容:

(gdb) 信息参数

使用每个断点(在每个函数调用处设置)记录此命令的结果会给出当前函数的参数。

于 2013-09-02T18:37:24.507 回答