strace 简介
跟踪系统调用和信号
1 | NAME |
安装strace
centos7 安装:yum install strace -y
跟踪特定进程
strace -ppid
使用 strace -p32557
https://segmentfault.com/a/1190000005931147
strace & ltrace & phpstrace
strace
strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用及它所接收的系统信息。追踪程序运行时的整个生命周期,输出每一个系统调用的名字,参数,返回值和执行消耗的时间等。
常用参数:
-p 跟踪指定的进程
-f 跟踪由fork子进程系统调用
-F 尝试跟踪vfork子进程系统调吸入,与-f同时出现时, vfork不被跟踪
-o filename 默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中
-ff 常与-o选项一起使用,不同进程(子进程)产生的系统调用输出到filename.PID文件
-r 打印每一个系统调用的相对时间
-t 在输出中的每一行前加上时间信息。 -tt 时间确定到微秒级。还可以使用-ttt打印相对时间
-v 输出所有系统调用。默认情况下,一些频繁调用的系统调用不会输出
-s 指定每一行输出字符串的长度,默认是32。文件名一直全部输出
-c 统计每种系统调用所执行的时间,调用次数,出错次数。
-e expr 输出过滤器,通过表达式,可以过滤出掉你不想要输出
这里特别说下strace的-e trace选项。
要跟踪某个具体的系统调用,-e trace=xxx即可。但有时候我们要跟踪一类系统调用,比如所有和文件名有关的调用、所有和内存分配有关的调用。
如果人工输入每一个具体的系统调用名称,可能容易遗漏。于是strace提供了几类常用的系统调用组合名字。
-e trace=file 跟踪和文件访问相关的调用(参数中有文件名)
-e trace=process 和进程管理相关的调用,比如fork/exec/exit_group
-e trace=network 和网络通信相关的调用,比如socket/sendto/connect
-e trace=signal 信号发送和处理相关,比如kill/sigaction
-e trace=desc 和文件描述符相关,比如write/read/select/epoll等
-e trace=ipc 进程见同学相关,比如shmget等
绝大多数情况,我们使用上面的组合名字就够了。实在需要跟踪具体的系统调用时,可能需要注意C库实现的差异。
比如我们知道创建进程使用的是fork系统调用,但在glibc里面,fork的调用实际上映射到了更底层的clone系统调用。使用strace时,得指定-e trace=clone, 指定-e trace=fork什么也匹配不上。
当发现进程或服务异常时,我们可以通过strace来跟踪其系统调用,“看看它在干啥”,进而找到异常的原因。熟悉常用系统调用,能够更好地理解和使用strace。
当然,万能的strace也不是真正的万能。当目标进程卡死在用户态时,strace就没有输出了。
这个时候我们需要其他的跟踪手段,比如gdb/perf/SystemTap等。
备注:
1、perf原因kernel支持
2、ftrace kernel支持可编程
3、systemtap 功能强大,RedHat系统支持,对用户态,内核态逻辑都能探查,使用范围更广
追踪多个进程方法
当有多个子进程的情况下,比如php-fpm、nginx等,用strace追踪显得很不方便。可以使用下面的方法来追踪所有的子进程。
1 | # vim /root/.bashrc //添加以下内容 |
追踪web服务
1 | # strace -f -F -s 1024 -o nginx-strace /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf |
追踪mysql
1 | # strace -f -F -ff -o mysqld-strace -s 1024 -p mysql_pid |
查看程序做了什么
1 | #!/bin/bash |
ltrace
-a 对齐具体某个列的返回值
-c 计算时间和调用,并在程序退出时打印摘要
-C 解码低级别名称(内核级)为用户级名称
-d 打印调试信息
-e 改变跟踪的事件
-f 跟踪子进
-h 打印帮助信息
-i 打印指令指针,当库调用时。
-l 只打印某个库中的调用。
-L 不打印库调用。
-n, –indent=NR 对每个调用级别嵌套以NR个空格进行缩进输出。
-o, –output=file 把输出定向到文件。
-p PID 附着在值为PID的进程号上进行ltrace。
-r 打印相对时间戳。
-s STRLEN 设置打印的字符串最大长度。
-S 显示系统调用。
-t, -tt, -ttt 打印绝对时间戳。
-T 输出每个调用过程的时间开销。
-u USERNAME 使用某个用户id或组ID来运行命令。
-V, –version 打印版本信息,然后退出。
-x NAME treat the global NAME like a library subroutine.
phpstrace
phpstrace追踪php进程
1 | Usage: ./php-strace [ options ] |