在调用函数时使GDB打印控制流程

17 c debugging gdb dynamic call-graph

如何调用感兴趣的gdb打印函数,根据堆栈的深度缩进?

我希望能够说出(制作):

(gdb) trace Foo* Bar* printf
Run Code Online (Sandbox Code Playgroud)

并让gdb打印所有以Foo或Bar开头的函数,因为它们被调用.有点像gnu cflow,除了使用调试符号和仅实际调用的打印函数,而不是所有可能的调用流.

无法帮助的工具包括cachegrind,callgrind和oprofile,它们最常调用函数的结果.我需要保留的调用顺序.

通配符(或等效的)是必不可少的,因为有很多Foo和Bar函数.虽然我愿意完全记录所有功能.或者,也许告诉gdb记录特定库中的所有函数.

某些GDB向导必须有一个用于此常见作业的脚本!

ale*_*lin 8

在你的情况下,我将转向definegdb中的命令,它允许您定义一个函数,该函数最多可以包含10个参数.

您可以将函数名称传递给"trace"作为您定义的函数的参数,或者将它们全部记录在函数本身中.我会做类似以下的事情

define functiontrace
if $arg0
    break $arg0
    commands
        where
        continue
        end
    end

if $arg1
...
Run Code Online (Sandbox Code Playgroud)

gdb中用户定义函数的参数引用为$ arg0- $ arg9.或者,您可以在函数中记录要跟踪的每个函数,而不是使用$ arg0-9.

注意:这不会缩进堆栈跟踪中的深度,但每次调用函数时都会打印堆栈跟踪.我发现这种方法比strace等更有用...因为它会记录你想要的任何函数,系统,库,本地或其他.


Sar*_*dhi 5

有 cmdrbreak接受正则表达式来设置断点。您可以使用:

\n\n
(gdb) rbreak Foo.*\n(gdb) rbreak Bar.*\n(gdb) break printf\n
Run Code Online (Sandbox Code Playgroud)\n\n

看到这个有关断点的详细信息,

\n\n

然后用于commands打印调用的每个函数。例如让 \xce\xb1 = 最后一个断点的编号(如果错过了可以检查一下)i br) ,然后执行:

\n\n
(gdb) commands 1-\xce\xb1\nType commands for breakpoint(s) 1-\xce\xb1, one per line.\nEnd with a line saying just "end".\n>silent\n>bt 1\n>c\n>end\n(gdb) \n
Run Code Online (Sandbox Code Playgroud)\n\n

一些详细说明:silent抑制不必要的信息性消息,bt 1打印回溯的最后一帧(即它是当前函数)ccontinue, 继续执行的快捷方式,以及end只是命令列表的分隔符。

\n\n

注意:如果您跟踪库函数,您可能需要等待 lib 加载。例如设置一个休息时间main或任何函数,运行应用程序直到该点,然后才设置您想要的断点。

\n


Pio*_*cki 1

您是否在这里看到了 litb 对类似帖子的出色回答?

他使用 readelf 来获取有趣的符号,使用 gdb 命令来获取跟踪,并使用 awk 来粘合所有这些。

基本上,您需要更改的是修改他的 gdb 命令脚本以从回溯中删除 1 深度以查看堆栈和过滤特定函数,并使用 awk/python/(...) 脚本重新格式化输出以将其呈现为树。(我承认我现在懒得做……)