目录:
(一)strace命令简介
(二)strace命令实战


(一)strace命令简介
(1.1)strace命令主要是用来监控我们程序的执行情况,当我们在Linux系统的用户空间运行一个程序的时候,Linux系统会将我们运行的程序封装成一个进程的形式,然后参与操作系统的调度,因此我们可以使用strace命令去跟踪我们的应用程序它的相关的运行情况,比如监控用户进程与内核进程的交互,以及跟踪进程的系统调用、信号传递、状态变化等。此时我们都可以通过这个strace命令去调试我们程序具体出错的原因。
(1.2)一般我们的系统调用主要包括①文件和设备访问:open、close、read、write、ioctl等;②进程管理:fork、clone、execve、exit等;③信号:signal、kill等;④内存管理:brk、mmap、mlock等;⑤进程间通信:semget、信号量、消息队列等;⑥网络通信:socket、connect等。
(1.3)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 cloumn:设置返回值的输出位置,默认为40
-e [expr]:指定一个表达式,用来控制如何跟踪,格式[qualifier=][!]value1[,value2]
qualifier只能是trace,abbrev,verbose,raw,singal,[read],[write]其中之一,value是用来限定的符号或数字,默认的qualifier是trace,感叹号是否定符号。例如:-eopen等价于-e trace=open,表示只跟踪open调用,而-etrace!=open表示跟踪除了open以外的其他调用,有两个特殊的符号all和none,注意有些shell使用!来执行历史记录里的命令,所以要使用\
-e trace=[set]只跟踪指定的系统,调用,例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用。默认的为set=all
-e trace=[file]只跟踪有关文件操作的系统调用
-e trace=process只跟踪有关进程控制的系统调用
-e trace=network跟踪与网络有关的所有系统调用
-e strace=signal跟踪所有与系统信号有关的系统调用
-e trace=ipc跟踪所有与进程通讯有关的系统调用
-e abbrev=set设定strace输出的系统调用的结果集,-v等与abbrev=none,默认为abbrev=all
-e raw=set将指定的系统调用的参数以十六进制显示
-e signal=set指定跟踪的系统信号,默认为all,如signal=!SIGIO,表示不跟踪SIGIO信号
-e read=set输出从指定文件中读出的数据,例如:-e read=3,5
-e write=set输出写入到指定文件中的数据
-o filename将strace的输出写入文件filename
-p pid跟踪指定的进程pid
-s strsize指定输出的字符串的最大长度,默认为32,文件名一直全部输出
-u username以username的UID和GID执行被跟踪的命令
(1.4)我们在系统中编辑一个strace.c的程序文件,然后写上如下的一段代码(图1-1),然后使用gcc编译strace.c程序后,在系统中会自动生成一个a.out的可执行文件,此时我们执行a.out的文件后系统出现了报错并生成了一个test.dat的文件(图1-2)。
【我的Linux,我做主!】strace指令调试详解_第1张图片
【我的Linux,我做主!】strace指令调试详解_第2张图片
(1.5)此时我们可以使用strace命令查看./a.out执行的时候相关系统调用的过程。
# strace ./a.out---查看./a.out执行的时候相关系统调用的过程
【我的Linux,我做主!】strace指令调试详解_第3张图片


(二)strace命令实战
(2.1)查看一个程序所有的open、close系统调用。
# strace -e open,close ./a.out---使用-e参数查看a.out执行文件的open和close的调用情况
【我的Linux,我做主!】strace指令调试详解_第4张图片
(2.2)查看每个系统调用消耗的时间。
# strace -T -e open,close ./a.out---我们使用-T参数可以查看系统每个系统调用所消耗的时间
【我的Linux,我做主!】strace指令调试详解_第5张图片
(2.3)统计系统调用次数、错误次数统计。
# strace -c -e open,close ./a.out---使用-c参数查看系统调用次数和错误次数统计
【我的Linux,我做主!】strace指令调试详解_第6张图片
(2.4)打印系统调用的时间戳。
# strace -t -T -e open,close ./a.out---使用-t命令可以查看系统调用的时间戳
# strace -tt -T -e open,close ./a.out---此时我们可以查看微秒级的系统调用的时间戳
【我的Linux,我做主!】strace指令调试详解_第7张图片
【我的Linux,我做主!】strace指令调试详解_第8张图片
(2.5)将跟踪日志保存到log文件中。
# strace -tt -T -e open,close -o log ./a.out---我们可以使用-o参数将跟踪日志保存到log文件中
【我的Linux,我做主!】strace指令调试详解_第9张图片
(2.6)最后我们再来分析一下使用strace -e来查看open系统调用后的问题与状态,当我们打开一个文件是成功的时候,那么系统会返回一个非负整数,所以系统在打开test.dat文件时,会返回一个3值,但是如果我们打开一个文件是失败的,那么系统会返回一个负数,所以此时系统打开并不存在的hello.dat文件时,返回的是-1值。由此我们便可以实现通过strace命令来查找程序运行报错原因的目标。
# strace -e open ./a.out---查看一个程序所有的open系统调用
【我的Linux,我做主!】strace指令调试详解_第10张图片

—————— 本文至此结束,感谢阅读 ——————