动态分析C语言代码生成函数调用关系的利器——gprof

gprof是一个C语言程序性能分析工具。在编译期间,我们给编译指令增加-pg选项,就可以将检测代码插入到源码中。然后使用gprof启动编译程序,它会收集程序运行的流程以及其他相关数据。最后我们使用gprof2dot将这些数据转换成dot文件,使用graphviz进行图形化展示。
在这里插入图片描述

《静态分析C语言生成函数调用关系的利器——cflow(二)》中的libevent为例。

准备工作

下载libevent代码

git clone https://github.com/libevent/libevent.git

安装编译依赖

sudo apt-get install libssl-dev

编译libevent

cd libevent
mkdir build && cd build
cmake ..     # Default to Unix Makefiles.
make

收集运行数据

编译插入检测代码的可执行程序

我们还是选用test-time.c为例子。
因为我们不希望使用静态库链接的形式,所以直接编译整个源码。
主要关注的就是-pg -c选项的新增,其他的命令我们在《静态分析C语言生成函数调用关系的利器——cally和egypt》已经见过。

gcc `find . -regextype posix-extended -regex '^./[^/]*\.c$' ! -name 'wepoll.c' ! -name 'win32select.c' ! -name 'evthread_win32.c' ! -name 'buffer_iocp.c' ! -name 'bufferevent_async.c' ! -name 'arc4random.c' ! -name 'event_iocp.c' ! -name 'bufferevent_mbedtls.c'` \
 ./test/test-time.c \
 -pg \
 -I./build/include/ -I./include -I./ \
 -L./build/lib/ -lcrypto -lssl \
 -DLITTLE_ENDIAN -D__clang__ \
 -UD_WIN32 -UDMBEDTLS_SSL_RENEGOTIATION \
 -o test-time

收集数据

执行下面指令,就能将程序运行的数据记录到test-time.output中。但是这个文件还是不能直接被图形化表达,需要进行一些处理。

gprof test-time > test-time.output

数据转换

上一步gprof采集的数据分为两部分,其中一个是调用关系(Call graph)

		     Call graph (explanation follows)


granularity: each sample hit covers 4 byte(s) for 100.00% of 0.01 seconds

index % time    self  children    called     name
                0.00    0.01       1/1           main [3]
[1]    100.0    0.00    0.01       1         event_base_dispatch [1]
                0.01    0.00       1/1           event_base_loop [2]
-----------------------------------------------
                0.01    0.00       1/1           event_base_dispatch [1]
[2]    100.0    0.01    0.00       1         event_base_loop [2]
                0.00    0.00   13033/13033       clear_time_cache [41]
                0.00    0.00   13032/13032       timeout_next [43]
                ……

这个数据格式我们需要转换成dot格式,以方便graphviz转换成图片。

环境准备

然后使用《管理Python虚拟环境的脚本》中的脚本构建虚拟环境,并安装gprof2dot

source env.sh init
source env.sh enter
source env.sh install gprof2dot

转换为dot

gprof2dot -e0 -n0  test-time.output>test-time.dot
digraph {
	graph [fontname=Arial, nodesep=0.125, ranksep=0.25];
	node [fontcolor=white, fontname=Arial, height=0, shape=box, style=filled, width=0];
	edge [fontname=Arial];
	1 [color="#ff0000", fontcolor="#ffffff", fontsize="10.00", label="event_base_dispatch\n100.00%\n(0.00%)\n1×"];
	1 -> 2 [arrowsize="1.00", color="#ff0000", fontcolor="#ff0000", fontsize="10.00", label="100.00%\n1×", labeldistance="4.00", penwidth="4.00"];
	2 [color="#ff0000", fontcolor="#ffffff", fontsize="10.00", label="event_base_loop\n100.00%\n(100.00%)\n1×"];
	2 -> 41 [arrowsize="0.35", color="#0d0d73", fontcolor="#0d0d73", fontsize="10.00", label="0.00%\n13033×", labeldistance="0.50", penwidth="0.50"];
	2 -> 42 [arrowsize="0.35", color="#0d0d73", fontcolor="#0d0d73", fontsize="10.00", label="0.00%\n13032×", labeldistance="0.50", penwidth="0.50"];
	2 -> 43 [arrowsize="0.35", color="#0d0d73", fontcolor="#0d0d73", fontsize="10.00", label="0.00%\n13032×", labeldistance="0.50", penwidth="0.50"];
	2 -> 45 [arrowsize="0.35", color="#0d0d73", fontcolor="#0d0d73", fontsize="10.00", label="0.00%\n13031×", labeldistance="0.50", penwidth="0.50"];
	2 -> 47 [arrowsize="0.35", color="#0d0d73", fontcolor="#0d0d73", fontsize="10.00", label="0.00%\n13031×", labeldistance="0.50", penwidth="0.50"];
	2 -> 49 [arrowsize="0.35", color="#0d0d73", fontcolor="#0d0d73", fontsize="10.00", label="0.00%\n13031×", labeldistance="0.50", penwidth="0.50"];
……

转换为图片

环境准备

sudo apt-get install graphviz

转换图片

dot test-time.dot -Tpng -o test-time.png

请添加图片描述

参考代码

https://github.com/f304646673/tools/tree/main/gprof2dot

参考资料

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

breaksoftware

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值