进程执行追踪命令strace

转载 · 04007 · 2021-03-01 · 原文

strace常用来跟踪进程执行时的系统调用和所接收的信号。Linux看进程不能直接访问硬件设备,当需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

strace命令的各参数备注如下:
-c 统计每一系统调用的所执行的时间,次数和出错的次数等. 
-d 输出strace关于标准错误的调试信息. 
-f 跟踪由fork调用所产生的子进程. 
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号. 
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪. 
-h 输出简要的帮助信息. 
-i 输出系统调用的入口指针. 
-q 禁止输出关于脱离的消息. 
-r 打印出相对时间关于,,每一个系统调用. 
-t 在输出中的每一行前加上时间信息. 
-tt 在输出中的每一行前加上时间信息,微秒级. 
-ttt 微秒级输出,以秒了表示时间. 
-T 显示每一调用所耗的时间. 
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出. 
-V 输出strace的版本信息. 
-x 以十六进制形式输出非标准字符串 
-xx 所有字符串以十六进制形式输出.
-a column   设置返回值的输出位置.默认 为40. 
-e expr   指定一个表达式,用来控制如何跟踪
-o filename   将strace的输出写入文件filename 
-p pid 跟踪指定的进程pid. 一般用于跟踪后台程序
-s strsize 指定输出的字符串的最大长度.默认为32. 
-u username  以username 的UID和GID执行被跟踪的命令

执行示例:

[on@B4471 ~]$ ps -ef | grep php
root     10984     1  0 19:13 ?        00:00:00 php-fpm: master process (/opt/soft/php7/etc/php-fpm.conf)
www      10985 10984  0 19:13 ?        00:00:00 php-fpm: pool www              
www      10986 10984  0 19:13 ?        00:00:00 php-fpm: pool www

追踪线程 10985,如下会列出执行过程中的系统调用函数

[on@B4471 ~]$ strace -p 10985 
fstat(10, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lseek(10, 0, SEEK_CUR)                  = 0
write(10, "{\"url\":\"http:\\/\\/newapi.shouji.b"..., 3790) = 3790
close(10)                               = 0
chdir("/home/onlinedev")                = -1 EACCES (Permission denied)
times({tms_utime=3, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 3013530754
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
fcntl(3, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0
write(4, "\1\6\0\1\0\6\2\0000\"}}]}\0\0\1\3\0\1\0\10\0\0\0\0\0\0\0.10", 32) = 32
shutdown(4, SHUT_WR)                    = 0
recvfrom(4, "\1\5\0\1\0\0\0\0", 8, 0, NULL, NULL) = 8
recvfrom(4, "", 8, 0, NULL, NULL)       = 0
close(4)                                = 0
munmap(0x7f7838000000, 2097152)         = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0

accept(0,上面显示的就是php线程执行时执行的系统函数,常见系统调用函数列表如下:

fork        创建一个新进程  
clone       按指定条件创建子进程  
execve      运行可执行文件  
exit        中止进程 
nanosleep   使进程睡眠指定的时间 
pause       挂起进程,等待信号 
wait        等待子进程终止   
waitpid     等待指定子进程终止  
socket      建立socket  
bind        绑定socket到端口  
connect     连接远程主机  
accept      响应socket连接请求  
send        通过socket发送信息  
recv        通过socket接收信息  
mmap        映射虚拟内存页
munmap      去除内存页映射  
mremap      重新映射虚拟内存地址   
msync       将映射内存中的数据写回磁盘   
listen      监听socket端口  
select      对多路同步I/O进行轮询  
shutdown    关闭socket上的连接  
readv       从文件读入数据到缓冲数组中  
writev      将缓冲数组里的数据写入文件  
pread       对文件随机读  
pwrite      对文件随机写  
lseek       移动文件指针    
dup         复制已打开的文件描述字    
flock       文件加/解锁   
poll        I/O多路转换   
truncate    截断文件

另外strace的-e trace选项详细

-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等
strace示例
1.跟踪nginx, 看其启动时都访问了哪些文件    strace -tt -T -f -e trace=file -o /data/log/strace.log -s 1024 2>&1 ./nginx
2. 定位程序异常退出    strace -ttf -T -p 10893 -o tmp -e trace=process 2>&1
3.程序启动加载文件    strace -e open,acces ./sh 2>&1 | grep fileName
4. 查选程序耗时    strace -c -p 11084
5.链接服务器失败    strace -e poll,select,connect,recvfrom,sendto nc www.baidu.com 80