• 进程监控工具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/

  • 相关阅读:
    怎样用HTML5 Canvas制作一个简单的游戏
    js面向对象
    javascript闭包
    javascript变量的作用域
    5-22
    5-23
    14-5-21 硬代码
    14-5-19 类和对象
    array
    生成干扰线
  • 原文地址:https://www.cnblogs.com/gean/p/12737116.html
Copyright © 2020-2023  润新知