函数调用堆栈追踪(2)

   在上一篇中介绍的2种方法都是在代码的某个特定的地方查看函数的调用关系,接下来介绍的2个工具可以追踪程序从main函数开始全部执行过的函数。

1.uftrace   

1.1安装

  工具在github上下载,地址如下:

 https://github.com/namhyung/uftrace

   readme里提供了一些简单的示例来说明uftrace的使用,这里主要针对稍复杂点的工程,演示程序以sqlite3为例,程序见:

http://blog.csdn.net/pfysw/article/details/78629167

   注意要加上-finstrument-functions对整个工程重新编译一遍,这个是用来导出函数符号表的,配置如下图

clip_image002

    在编译安装uftrace 之前要先安装elfutils,先下载elfutils-0.161,地址如下:

https://sourceware.org/elfutils/ftp/

解压后编译安装:

./configure --prefix=/usr --program-prefix="eu-" &&
make
make install

然后再安装uftrace,也是安装3部曲:

./configure  make  make install

安装过程可能有很多坑,我来说下我碰到的:

如果gcc版本是4.4.7,编译能通过,但是使用时会出现:“mcount: /home/qxqb/work/uftrace-master/libmcount/plthook.c:798:plthook_entry

 ERROR: invalid function idx found! (idx: 952/202, module:”的错误

gcc版本切换到4.6.3编译后没有问题。

另外我还把gcc升级到4.8.5,这时eclipse自动编译的程序debug时会出现No source available for "main() at 0x80488e9"的错误,需要手动在编译选项设置里添加-gstabs+才不会报错,而4.6.34.4.7没有这个问题。

1.2使用

uftrace支持的子命令有:

 * `record` : runs a program and saves the trace data
 * `replay` : shows program execution in the trace data
 * `report` : shows performance statistics in the trace data
 * `live`   : does record and replay in a row (default)
 * `info`   : shows system and program info in the trace data
 * `dump`   : shows low-level trace data
 * `recv`   : saves the trace data from network
 * `graph`  : shows function call graph in the trace data
 * `script` : runs a script for recorded trace data

 可以通过uftrace  --help命令来查看操作选项,如:

--auto-args :显示函数参数和返回值

-F:仅追踪某个函数

 -t:过滤掉执行函数小于某个值的函数

 -k:显示内核函数

 ……

 接下来开始演示怎么使用,新建一个文件夹mytest,并把要追踪的程序tclsqlite放到该文件夹下,新建一个文件tclscript

sqlite3 db file:example1.db?mode=memory&cache=shared
db eval {CREATE TABLE t1(a TEXT, b INTEGER)}
db eval {
   INSERT INTO t1 VALUES('one',1);
   INSERT INTO t1 VALUES('two',2);
   INSERT INTO t1 VALUES(NULL,3);
}
db eval {SELECT * FROM t1} {
   puts "a=$a b=$b"
}

cd进入该文件夹并生成跟踪记录:

cd ./mytest

uftrace --auto-args record tclsqlite tclscript

然后把跟踪记录导出到文件,这里有2种方式,一种是replay:

uftrace replay>trace_replay

clip_image004

另外一种是dump模式

uftrace dump>trace_dump

clip_image006

我在使用-k时出现了以下错误:

uftrace -k record tclsqlite tclscript

WARN: kernel tracing disabled due to an error

does CONFIG_FTRACE enable in kernel?

暂时不知道什么原因,有2种思路解决,一种是去/sys/kernel/debug/tracing目录下找到相关文件配置一下,试了一下把tracing_enabledtracing_on都打开:

echo 1 > tracing_enabled

echo 1 > tracing_on

好像也没什么效果,可能还有哪些配置要改,这个就需要进一步了解linux内核的调试工具ftrace

另外一种思路就是调试uftrace源码了,看看到底在哪里出错了,以后有时间再来解决这个问题吧。

2.ftrace

2.1示例

这里的ftrace并不是指内核的ftrace,而是github上有人写的一个追踪函数执行过程的工具,地址如下:

https://github.com/finaldie/ftracer

当然githubftrace工具还有很多,大家可以都尝试一下,这个我用了还不错,所以在这里介绍一下。

解压后,cd进入./example/c文件夹,首先看一个例子

make

./run.sh

这时候会生成追踪记录保存在/tmp/trace.txt,我们需要把记录导出来:

cd 进入tools文件夹,执行:

./gen_report.sh -e ../example/c/test -f /tmp/trace.txt

然后就生成了report文件,总共有3个线程,每个线程都生成一个报告

thread(3067386688) report generate complete at /tmp/trace_report.3067386688
thread(3075779392) report generate complete at /tmp/trace_report.3075779392
thread(3075782336) report generate complete at /tmp/trace_report.3075782336
cat  /tmp/trace_report.3067386688
 1x work(/home/qxqb/work/ftracer-master/example/c/test.c:50) - (called from ??:0)
.. 3x a(/home/qxqb/work/ftracer-master/example/c/test.c:43) - (called from test.c:51)
.... 1x b(/home/qxqb/work/ftracer-master/example/c/test.c:27) - (called from test.c:46)
...... 1x c(/home/qxqb/work/ftracer-master/example/c/test.c:22) - (called from test.c:32)
...... 1x f(/home/qxqb/work/ftracer-master/example/c/test.c:7) - (called from test.c:32)
.... 1x b(/home/qxqb/work/ftracer-master/example/c/test.c:27) - (called from test.c:46)
...... 2x d(/home/qxqb/work/ftracer-master/example/c/test.c:17) - (called from test.c:34)
...... 1x e(/home/qxqb/work/ftracer-master/example/c/test.c:12) - (called from test.c:38)

如果要以网页的形式生成报告,打开gen_report.sh,找到output_format=,改为output_format=html,网页的优势是支持折叠和展开,看起来比较方便。

2.2使用

仍然以tclsqlite这个程序为例,在example目录里新建一个文件夹mytest,把上面说到的tclsqlite tclscript文件放到该目录下,新建run.sh文件:

#!/bin/sh
export LD_PRELOAD=../../src/ftracer.so
./tclsqlite  tclscript

然后运行./run.sh生成记录。

tools目录下生成报告:

./gen_report.sh -e ../example/mytest/tclsqlite -f /tmp/trace.txt

这时发现生成的报告竟然还是上一次的test程序的记录,因为ftrace并不会清理上一次生成的记录,需要手动清理,解决的办法是进入/tmp/文件夹,把以下选中的文件删掉:

clip_image008

/tmp/html文件夹也删掉,如果没权限,进入sudo nautilus模式就有权限了。

再重复开始的步骤就得到追踪的报告的html文件:

trace_report.3073885888.html

clip_image010

有了这个之后我们就可以很方便地查找某段代码的上下文了。

3.结束

这是以上例子中生成的针对sqlite3的函数追踪报告的下载:

http://download.csdn.net/download/pfysw/10254999

里面有trace_replayuftrace_dumptrace_report.3073885888.html

除了这里介绍的2个工具,还有一些别的工具如rrvalgrind等应该也还是不错的,功能更强大,有时间的朋友也可以研究一下。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值