最近遇到了奇怪的现象,一个进程的物理内存使用量为 7MB 左右,但分配了 250MB左右的地址空间,程序中没有映射大的文件。代码量太大,从源码找问题 不现实,还好有 strace+ 这神器,它可以跟踪系统调用和各种信号,它收集到的 信息还能保持高可读性。相比 strace,strace+ 还能够记录系统调用的调用栈,这样 可以方便的看出到底是谁调用了它。它也是分析源码和简单分析性能瓶颈的好工具。
ptrace 函数是 strace 实现的关键,通过 ptrace 可以操作其他进程的内存,设置断点等。

long ptrace(enum __ptrace_request request, pid_t pid,
                   void *addr, void *data);

strace+ 源码托管在 googlecode 上,它的文档也没有 同步更新。

安装

$ git clone https://code.google.com/p/strace-plus/
$ autoreconf -f -i
$ ./configure
$ make
$ cp strace strace+

编译生成的 strace+ 和 strace 的用法一样,但有件事在 Quick-start guide 没到提到, 那就是如果想要 strace+ 生成带有调用栈的信息,必须指定 strace+ 的 -k 参数,否则效果 会和 strace 一样。我为此折腾了好久,最后在 Quick-start guide should include ‘-k’ 中找到答案(这算是开源软件的特点吧:缺乏文档。); )。

先跑一下官网的 demo,执行

$ strace+ -o hello.out ./hello

解析 hello.out 查看调用栈

$ python scripts/pretty_print_strace_out.py hello.out --trace

或者以树的形式查看调用栈

$ python scripts/pretty_print_strace_out.py hello.out --tree

使用

strace+ 的使用方式如下:

$ strace [-CdffhiqrtttTvVxxy] [-In] [-eexpr]... [-acolumn] [-ofile] [-sstrsize] [-Ppath]... -ppid... / [-D] [-Evar[=val]]... [-uusername] command [args]

$ strace -c[df] [-In] [-eexpr]... [-Ooverhead] [-Ssortby] -ppid... / [-D] [-Evar[=val]]... [-uusername] command [args]

strace 常用选项


应用场景

可以参考下面的文章。

  1. 7 Strace Examples to Debug the Execution of a Program in Linux
  2. Chapter 17. Tracing Tools

参考链接

  1. strace-plus
  2. Building strace-plus