用GCC来跟踪程序的函数调用关系

GCC就像一个巨大的宝藏,只要你愿意花时间,总能淘到好东西。

 

在看一些大中型的软件的源代码时,你是不是非常希望有一个工具能够方便的生成各个函数之间的调用关系图呢?

为了实现这个目标,你可以通过对源代码进行静态扫描得到函数的调用关系,但是你无法通过这种方法获得更多的信息,

(如:对某个函数的调用次数,被调用的函数执行了多长时间等,这些信息对于软件的优化具有很好的参考价值)除了

静态扫描之外,还存在一些动态的方法,即在程序的运行过程中记录相关的信息,不过这些动态的方法通常都需要有编

译器的支持,通过编译器在编译的过程中插入相应的代码。下面简单的介绍一下,GCC的function instrumentation

机制。

 

简单的来说,gcc function instrumentation就是在每个函数调用之前调用一个名为__cyg_profile_func_enter的函数,

在函数调用介绍的时候调用__cyg_profile_func_exit。这两个函数在gcc看来只是两个普通的函数,是可以由用户自己进行

定制的。下面先看个例子:

 

 

编译与运行:

$ gcc -finstrument-functions hello.c -o hello

$ ./hello

__cyg_profile_func_enter: func = 0x8048468, called by = 0xb7e36ebc

Hello World!

__cyg_profile_func_exit: func = 0x8048468, called by = 0xb7e36ebc

 

呵呵,是不是很神奇,只需要在软件中简单加入__cyg_profile_func_enter  __cyg_profile_func_exit这两个函数的定义,

然后再编译的时候加上-finstrument-functions选项,就可以在每个函数调用前后调用这两个函数获取你所感兴趣的信息。为了

对其具体的实现细节有所了解,可以通过”objdump -d hello“来看下程序反汇编之后的结果。

 

从上面的汇编代码可以看出,gcc是在进入函数完成堆栈的初始化之后调用__cyg_profile_func_enter的,在函数返回清理堆栈

之前调用__cyg_profile_func_exit的。

 

经过上面的步骤,我们还只能获取到函数调用时的信息,还没有获取到函数之间的调用关系,但是明白了上述的原理之后,参看参看

参考资料[1]就能够很容易的实现目标了。

 

参考资料

[1] http://www.ibm.com/developerworks/cn/linux/l-graphvis/

[2] http://blog.linux.org.tw/~jserv/archives/001870.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值