进程监控工具strace

strace是什么?

linux syscall tracer(linux系统调用追踪器)

官网:strace是用于Linux的诊断、调试的用户空间追踪程序。

我认为他是一个用来看某一进程大概在干什么的工具。

strace能做什么?

官网:它可以用于监视和修改进程与Linux内核之间的交互,包括系统调用,信号传递和进程状态。

举个简单的例子:

#include <stdio.h>
#include <stdlib.h>

int main()
{
        char dataPtr[] = {'H','e','l','l','o','!','
'};
        FILE *fpw = fopen("test/file_test","a");
        fwrite(dataPtr,sizeof(char),7,fpw);
        fclose(fpw);
        FILE *fpo = fopen("test/file_test","r");
        char buffer[1024];
        int readCnt = fread(buffer,sizeof(buffer),1,fpo);
        fclose(fpo);
        printf("%s
",buffer);
        return 0;
}

编译运行发现报错“段错误”。

这个时候我们一般会gdb调试看看到底错在哪了,像这样:

但是这篇文章讲的是strace所以我们也可以这样:

我们通过两种方法都可以准确的找到问题:test文件夹是不存在的
但是如果我们现在只有没有调试信息的二进制包呢?那strace显然更具优势。
而且如果我们在定位一个代码量十分庞大的问题时,在不明确问题具体出在哪片代码的时候,用gdb逐行去调,效率比较低下。
所以我们可以通过strace直接先跑一下定位到具体位置,如果没有解决我们在gdb仔细看。

OK,我们现在应该知道strace能做的是:打开应用进程的这个黑盒,通过系统调用的线索,告诉你进程大概在干嘛。

strace怎么用?

strace有两种运行模式:

  1. 通过它启动要跟踪的进程。
    # strace ./a.out
  2. 通过进程号跟踪已经在运行的进程。
    # strace -p 12345

strace用很多参数可以使用,可以通过man strace去仔细研究,这里我只讲一些我比较熟悉的参数:

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

首先我们看'-tt'和'-T':

这里可以看到在每行输出的最前面多了时间,最后面多了花销的时间。
有了这两个参数我们就很容易找到进程哪里跑的慢了。

'-v':

客户的环境可能有自己的环境变量,不同的环境变量会导致进程调用的东西不一样,结果也可能不一样。
不要小看这个问题,经常会有客户遇到这种问题。

'-f':
这里我们换个例子:

#include<unistd.h>
#include<stdio.h>
int main (){
	pid_t pid;
	int count=0;
	pid=fork();
	if(pid<0)
		printf("error in fork!");
	else if(pid==0){
		printf("i am the child process, my process id is %d
",getpid()); 
		count++;
	}
	else{
		printf("i am the parent process, my process id is %d
",getpid()); 
		count++;
	}
	printf("count=%d
",count);
	return 0;
}


多进程的程序如果只看父进程可能会忽略子进程,所以不要忘了加上-f

'-e':
继续文件操作的例子,

有时候strace输出的记录太多了,很难看,我们很难找到想要的记录,这时候只要加上-e只看想看的就可以了。

'-o':

有时候strace输出的记录太多了,终端显示行数不够,导致看不全。
或者用脚本跑的时候人不在,我们就可以通过-o输出到文本。

'-s':

默认只显示32个字节,但是我们要看的内容很长,可以通过-s来多显示一点。

'-p':

就是通过pid查看正在运行的进程。

总结

综上所述我们可以通过strace解决很多系统调用问题,也能通过strace辅助我们调查问题。
虽然strace很强大,但是他解决不了只在用户态的问题,所以我们还是要好好学习gdb、perf等。

个人博客:https://geanqin.github.io/

原文地址:https://www.cnblogs.com/gean/p/12737116.html