在应用程序中进行的所有函数调用的列表

bro*_*oun 21 callstack gdb gprof

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

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

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

Emp*_*ian 24

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

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

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

nm /path/to/a.out | egrep ' [TW] '
Run Code Online (Sandbox Code Playgroud)

您还可以使用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
Run Code Online (Sandbox Code Playgroud)

一旦继续,你将为每个被调用的函数命中一个断点.使用disablecontinue命令继续前进.除非你想使用Python脚本,否则我不相信有一种简单的自动化方法.

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

  • 自从我输入命令“rbreak”以来,gdb 的 cpu 利用率一直处于 100%。 (4认同)
  • 注意:这也会破坏在`_start`之前运行的代码:http://stackoverflow.com/questions/31379422/why-is-init-from-glibcs​​-csu-init-first-c-known-before-start -即使-如果-开始-i (2认同)
  • 如果你只想在非系统函数上设置断点,你可以试试 `rbreak ^s[^@]*$`,即排除 `malloc`、`strlen` 等。 (2认同)
  • @Johannes我认为你需要在“^”之后删除“s” - 我得到的只是从 s 开始的非系统函数... (2认同)

vy3*_*y32 9

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


Cir*_*四事件 6

记录功能 - 呼叫历史记录

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

如果您是少数支持英特尔处理器跟踪(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
Run Code Online (Sandbox Code Playgroud)

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

start
record btrace
Run Code Online (Sandbox Code Playgroud)

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

 Target does not support branch tracing.
Run Code Online (Sandbox Code Playgroud)

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

相关主题:

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