使用strace工具跟踪系统调用和信号

1.1.  

1.1.1.   strace介绍

       strace是一个很有用的诊断、学习、调试工具。使用时无需重新编译程序,这也使得可以用来跟踪没有源代码的程序。系统调用和信号是发生在用户空间和内核空间边界处的事件,检查这些边界事件有助于隔离错误、检查完整性、跟踪错误。

       使用starce工具来执行程序时,它会记录程序执行过程中调用的系统调用、接收到的信号。通过查看记录结果,可以知道程序打开了哪些文件(open)、打开是否成功、对文件进行了哪些读写操作(read/write/iotcl等)/映射了哪些内存(mmap)、向系统申请了多少内存等。

1.1.2.   strace 移植

       strace的源码为/work/debug/strace-4.5.15.tar.bz2,在arm平台上使用时要打上补丁strace-fix-arm-bad-syscall.patch

       首先执行以下命令给strace打上补丁。

$tarxjf starce-4.5.15.tar.bz2

$catstarce-4.5.15

$patch–pl < strace-fix-arm-bad_syscall.patch

       然后在strace-4.5.15目录下执行以下命令编译strace

$./configure–host=arm-linux CC=arm-linux-gcc

$make

       在strace-4.5.15目录下生成一个名为strace的可执行程序,将它复制到开发板上根文件系统上即可使用。

1.1.3.   使用strace来调试程序

1.1.3.1.           strace的用法

执行strace -help可以看到它的用法,如下所示:

下面是几个常用的选项

-f:除了跟踪当前进程外,还跟踪其子进程。

-o file:将输出信息写到文件中,而不是显示到标准错误输出。

-p pid:绑定到一个由pid对应的正在运行的进程,此参数常于调试后台进程。

-t :打印各系统调用被调用时的绝对时间,可以观察程序各部分的执行的时间。

-tt:与-t选项相似,打印时间精度为us。

-r:与-t选项相似,打印相对时间。

1.1.3.2.           strace输出结果分析

       通过strace,可以看到程序运行的细节。

       运行strace cat /dev/null,可以看到它的输出结果如下,其中省略号表示还有其它系统调用没有列出来。

       第一行表示shell进程通过系统调用execve来建立一个进程,即”cat /dev/null”对应的进程。

       后面几行是open打开动态链接库,如果是静态程序连接的,这几个步骤将不需要。

       然后“cat /dev/null”命令才是真正处理过程,首先打开“dev/null”文件,然后读取它的内容。

       在strace的输出结果中,每一行对应一个系统调用:左起是系统调用的名字,紧接着是被包含在括号中的参数,最后是它的返回值。

       系统调用出错时(返回值通常是-1),在返回值的后面会打印错误记号及其注释。

       接收到信号时(如CTRL+C发送的SIGINT信号)也会将信号记号及其注释打印出来。

$strace–o sleep.log sleep 100 &

$kill–INT 868 // ps  =>  sleep pid = 868

       在sleep.log文件中可以发现如下字样,表示接收到SIGINT信号:

---SIGINT (Interrupt ) @ 0  (0) –

+++kill by SIGINT +++

1.1.3.3.           调试程序

 

       在移植基于X的GUI程序时,就多次使用strace工具来跟踪程序,根据其中的出错信息建立了一些必需的目录,复制字库到特定的目录等。当不了解一个程序依赖于哪些目录和文件时,可以用strace工具来跟踪它。

       下面举几个例子来说明如何使用strace来调试程序。

       (1)使用strace来定位gtkboard的警告信息。

       在移植hgtkboard时,它启动后在串口控制台上可以看到如下警告信息:

       (gtkboard:855): Gdk-WARNING**: Error converting from UTF-8 to STRING:

Conversionfrom character set ‘UTF-8’ to ‘ISO-8859-1’ is not supported

       解决办法为:把编译器lib目录下的gconv文件夹复制到开发板根文件系统的/usr/lib目录中。

       是怎么知道这个解决方法的呢?如果深入分析gtkboard的代码,自然可以知道解决方法,但是效率太低,可以借助strace来分析。

       通过以下命令启动gtkboard。

       #strace –o gtkboard.loggtkboard &

       然后查看gtkboard.log文件,发现如下字样:

       open(“/usr/lib/gconv/gconv-modules.cache”,O_RDONLY)= -1 ENOENT(no such file or directory)

       write(2,”\n(gtkboartd:855):Glib-WARNING**”…, 82) = 82

       而交叉编译工具链中lib目录下刚好有gconv目录,把它复制到开发板根文件系统的/usr/lib目录后重新启动gtkboard,这些警告信息消失。

       (2)使用strace来测量程序的执行时间。

       如果发现某个程序突然执行很慢,通常需要找出其中哪部分代码执行的时间过长,使用strace工具可以轻易达到这个目的。

       执行strace –r sleep 2命令,可以发现第2行和第3行的时间相差2s左右,符合”sleep 2”的意图。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值