如何快速搞懂代码调用流程

例如想搞懂wget这个软件的代码实现:

  • 下载wget 源码
  • 编译debug版本的binary (取消编译优化选项)
  • 导出函数符号
 $ nm wget | grep '[0-9a-z] [tT]' > wget.map 
  • gdb 7.0 以后版本支持python 扩展,可用python 脚本调用gdb 命令。 写个简单的 gdb_wget.py,目的是将所有的函数打上断点,断住后打印调用栈并继续运行:
$ cat gdb_wget.py
gdb.execute("set logging on")
gdb.execute("set height 0")

f = open("wget.map", 'r')
for line in f:
	gdb.execute("b " + line[19:len(line)-1]);
f.close()

gdb.execute("run www.baidu.com");

while 1:
	gdb.execute("bt");
	gdb.execute("c");
  • 运行gdb 调试wget,将所有输出保存到gdb.log中,起来后执行 source gdb_wget.py, 控制权交给python 脚本。
$ gdb ./wget | tee gdb.log
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./wget...done.
(gdb) source gdb_wget.py 
...............

运行结果见下图(1),左边部分,得到wget运行时执行到的所有函数及调用栈。
下图(2): 写个程序parse gdb.log, 得到可读性很好的程序运行路线。
下图(3): 在Emacs中折叠部分非重要函数调用过程,高亮显示重点函数,我相信一眼即可理解wget大致代码原理。

就算我死磕代码,花大量时间研究得很透彻,我相信过了一个多月,头脑里剩下保存的差不多也就图(3)显示的调用过程。
而用这种方法,整个过程不到5分钟。
如果要我在wget的代码上增加个新功能,我就顺着这些调用过程,在恰当的位置加些函数实现。

当然除了显示图(3)的样子外,还可以显示成类似UML格式的,只要有了原始的raw格式数据,即可将它们转成画图工具的输入数据,生成适合自己理解的图。
我收集的辅助画图工具:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值