strace两种运行模式:
一种是通过它启动要跟踪的进程。用法很简单,在原本的命令前加上strace即可。比如要跟踪”ls -lh /var/log/messages” 这个命令的执行,可以这样:
# strace ls -lh /var/log/messages

另外一种运行模式,是跟踪已经在运行的进程,在不中断进程执行的情况下,理解它在干嘛。这种情况,给strace传递个-p pid 选项即可。比如,有个在运行的some_server服务,
第一步,查看pid:
# pidof some_server                      
17553
得到其pid 17553然后就可以用strace跟踪其:
# strace -p 17553
完成跟踪时,按ctrl + C 结束strace即可。

strace常用参数:
-tt 在每行输出的前面,显示毫秒级别的时间
-T 显示每次系统调用所花费的时间
-v 对于某些相关调用,把完整的环境变量,文件stat结构等打出来
-f 跟踪目标进程,以及目标进程创建的所有子进程
-e 控制要跟踪的事件和跟踪行为,比如指定要跟踪的系统调用名称
-o 把strace的输出单独写到指定的文件
-s 当系统调用的参数是字符串时,最多输出指定长度的内容,默认32字节
-p 指定要跟踪的进程pid, 要同时跟踪多个pid, 重复多次-p选项即可。

实例:
跟踪nginx, 看其重启时都访问了哪些文件

# strace -tt -T -f -e trace=file -o strace.log -s 1024 ./nginx -s reload
部分输出:

进程的pid, 接着是毫秒级的时间,这个是 -tt 选项的效果。每一行的最后一列显示了该调用所花的时间,是 -T选项的结果。这里的输出只显示和文件访问有关的内容,就是通过-e trace=file参数指定的。

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时,需指定 -etrace=clone, 若指定-e trace=fork 什么也匹配不上。 

附:关于系统调用:
       在计算机中,系统调用(英语:system call),又称为系统呼叫,指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供用户程序与操作系统之间的接口。操作系统的进程空间分为用户空间和内核空间:操作系统内核直接运行在硬件上,提供设备管理、内存管理、任务调度等功能。用户空间通过API请求内核空间的服务来完成其功能——内核提供给用户空间的这些API, 就是系统调用。在Linux系统上,应用代码通过glibc库封装的函数,间接使用系统调用。
Linux内核目前有300多个系统调用,详细的列表可以通过 syscalls 手册页查看。这些系统调用主要分为几类:
1、文件和设备访问类:open/close/read/write/chmod 等
2、进程管理类:fork/clone/execve/exit/getpid 等
3、信号类:signal/sigaction/kill 等
4、内存管理:brk/mmap/mlock 等
5、进程间通信:IPC shmget/semget *信号量,共享内存,消息队列等
6、网络通信:socket/connect/sendto/sendmsg 等
7、其他。null

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注