我们如何列出应用程序中调用的所有函数。我尝试使用GDB,但它的回溯列表只能到主函数调用。
我需要更深入的列表,即main函数调用的所有函数列表以及从这些调用函数调用的函数等等。
有没有办法在gdb中获取此功能?或者你可以给我一些关于如何获得这个的建议吗?
答案 0 :(得分:21)
我们如何列出在应用程序中调用的所有函数
对于任何实际大小的应用程序,此列表将包含数千个条目,这可能会使它无用。
您可以使用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
一旦继续,你将为每个被调用的函数命中一个断点。使用disable
和continue
命令继续前进。我不相信有一种简单的自动化方法,除非您想使用Python脚本。
已经提到gprof
是另一个不错的选择。
答案 1 :(得分:9)
您需要一个通话图表。您要使用的工具不是gdb,而是gprof
。您使用-pg
编译程序,然后运行它。运行时,将生成文件gmon.out
。然后使用gprof
处理此文件并享受输出。
答案 2 :(得分:6)
记录功能 - 通话记录
https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html
如果您是支持Intel Processor Tracing的少数人(2015年)之一,那么这应该是一个很好的硬件加速可能性(英特尔PT,intel_pt
在{ {1}})。
GDB文档声称它可以产生如下输出:
/proc/cpuinfo
在使用之前,您需要运行:
(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
这是一个无能力CPU失败的地方:
start
record btrace
在How to run record instruction-history and function-call-history in GDB?
进一步讨论了CPU支持相关主题:
对于嵌入式,您还可以考虑JTAG和支持ARM DSTREAM等硬件,但x86支持似乎不太好:debugging x86 kernel using a hardware debugger
答案 3 :(得分:3)
这个问题可能需要澄清,以确定目前2个答案之间的答案。取决于您的需求:
1)您需要知道每个函数以与调用#匹配的函数的直列表/图形格式调用多少次。如果您的代码不是程序性的(即函数在分支结构中调用其他函数而没有调用什么的模糊性),这可能导致模糊/不确定的结果。这是基本的gprof功能,需要使用-pg标志重新编译。
2)您需要按照调用顺序排列函数列表,这取决于您的程序,这是最佳/可行的选项: a)如果您的程序运行并终止而没有运行时错误,您可以使用gprof来实现此目的。 b)上面使用带有日志记录和断点的dbg的ELSE选项是我在阅读本文时学到的剩余选项。
3)您不仅需要知道顺序,还需要知道每个调用的函数参数。我目前的工作是粒子传输物理学中的模拟,所以这绝对有助于追踪异常结果来自哪里......即当传递的参数停止有意义时。我想这样做的一种方法是使用俄罗斯人的做法的变化,除了使用以下内容:
(gdb)info args
使用每个断点(在每个函数调用时设置)记录此命令的结果将给出当前函数的参数。