strace介绍
strace是一个在 Linux 系统下用于跟踪系统调用和信号的工具。通过 strace,可以看到进程是如何与内核交互的,包括哪些系统调用被调用、它们的参数是什么,以及它们的返回值。这对于调试和性能分析非常有用。
使用方法
sudo strace -C ./testapp
或者
sudo strace -C -p 17142
上述17142是testapp这程序运行起来后的pid。运行strace后就一直不停地监控和打印信息,需要停止时按ctrl+c。停止后,打印的内容如下所示。
strace: new tcb for pid 17142, active tcbs:1
strace: Process 17142 attached
select(19, [3 4 5 6 7 8 9 11 17 18], [], [5 6 9], {tv_sec=0, tv_usec=2558}) = 0 (Timeout)
select(19, [3 4 5 6 7 8 9 11 17 18], [], [5 6 9], {tv_sec=0, tv_usec=9999}) = 0 (Timeout)
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
50.46 0.033975 101 336 select
33.99 0.022886 176 130 sendto
15.54 0.010465 81 130 recvfrom
------ ----------- ----------- --------- --------- ----------------
100.00 0.067326 596 total
常用参数
strace有很多参数,运行strace -h可以查看到完整的帮助信息。下面介绍一些日常开发中常用到的参数。
输出格式类参数:
-k:在每个系统调用打印调用堆栈
-o:选项将输出重定向到文件中,而不是显示在终端上
-r:打印两次系统调用之间的间隔时间,-r与-tt不可同时用
-tt:打印精确到微秒的调用该系统函数时的时间戳,-r与-tt不可同时用
-T:打印每个系统调用花费的时间
-y 打印与文件描述符参数相关的路径
-yy 打印与套接字文件描述符相关的特定于协议的信息
统计类参数:
-c:统计每个系统调用的时间、调用次数和错误,并报告摘要
-C :类似 -c,但也打印常规输出
-S sortby 按以下方式排序系统调用计数:时间、调用次数、名称、无(默认为时间)
-w 总结系统调用的延迟(默认为系统时间)
过滤类参数:
-e:expr 一个限定表达式:option=[!]all 或 option=[!]val1[,val2]…
选项: trace, abbrev, verbose, raw, signal, read, write, fault
其中的trace选项最常用,trace=后面可选的值有:
network:跟踪与网络相关的系统调用(如 socket, bind, connect, send, recv 等)
process:跟踪与进程管理相关的系统调用(如 fork, exec, exit 等)
signal:跟踪与信号相关的系统调用(如 kill, sigaction, sigprocmask 等)
ipc:跟踪与进程间通信(IPC)相关的系统调用(如 msgget, msgsnd, msgrcv, semget, semop, shmget, shmat, shmdt 等)
例如只跟踪网络相关的系统调用:
sudo strace -C -e trace=network -p 17142
-P:path 跟踪对路径的访问
跟踪类参数:
-f : 当被跟踪的进程调用 fork 或 vfork 时,也跟踪子进程
-ff :同-f,但将输出到单独的文件
其他:
-v :详细模式:打印未缩写的argv、stat、termios等参数
常用参数组合
最常用的把全部日志打印到log.txt文件的参数组合如下所示:
sudo strace -o log.txt -rTCf -p 17142
如果想看到程序启动时,加载了哪些so库,则需要用strace启动程序,例如:
sudo strace -o log.txt -rTCf ./testapp
分析log.txt 日志文件后,想详细看socket的收发端口和IP,再加上-yy参数。想详细看读写文件路径,再加上-y参数。想详细看系统调用API的参数,再加上-v参数。如果想看某个系统调用在源码哪里调用的,可以加上-k参数。