神器之strace
https://www.jianshu.com/p/33521124bdf2
strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用。
Strace是一个简单的跟踪系统调用执行的工具。在其最简单的形式中,它可以从开始到结束跟踪二进制的执行,并在进程的生命周期中输出一行具有系统调用名称,每个系统调用的参数和返回值的文本行。
在Linux中,进程是不能直接去访问硬件设备的,比如读取磁盘文件、接收网络数据等,但可以将用户态模式切换到内核模式,通过系统调用来访问硬件设备。这时strace就可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间、调用次数,成功和失败的次数。
strace能做什么
- 它可以基于特定的系统调用或系统调用组进行过滤
- 它可以通过统计特定系统调用的使用次数,所花费的时间,以及成功和错误的数量来分析系统调用的使用。
- 它跟踪发送到进程的信号。
- 可以通过pid附加到任何正在运行的进程。
- 调试性能问题,查看系统调用的频率,找出耗时的程序段
- 查看程序读取的是哪些文件从而定位比如配置文件加载错误问题
- 查看某个php脚本长时间运行“假死”情况
- 当程序出现“Out of memory”时被系统发出的SIGKILL信息所kill
另外因为strace拿到的是系统调用相关信息,一般也即是IO操作信息,这个对于排查比如cpu占用100%问题是无能为力的。这个时候就可以使用GDB工具了。
phptrace
因为strace只能追踪到系统调用信息,而拿不到php代码层的调用信息。phptrace扩展就是为了解决这个问题,phptrace包含两个功能:1. 打印当前PHP调用栈,2. 实时追踪PHP调用。这样就能更方便我们去查看到我们需要的信息。phptrace wiki
strace的使用
1、找出程序在启动时读取的配置文件
[root@localhost ~]# strace php 2>&1 | grep php.ini open("/Data/apps/php7/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory) open("/Data/apps/php7/etc/php.ini", O_RDONLY) = 3
2、使用strace来跟踪cat查看一个文件做了什么
[root@localhost mau]# strace cat index.php
execve("/usr/bin/cat", ["cat", "index.php"], [/* 27 vars */]) = 0 brk(0) = 0x60d000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff9000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=106900, ...}) = 0 mmap(NULL, 106900, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fde000 close(3) = 0 open("/usr/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\34\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=2107768, ...}) = 0 mmap(NULL, 3932736, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7a1b000 mprotect(0x7ffff7bd1000, 2097152, PROT_NONE) = 0 mmap(0x7ffff7dd1000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7ffff7dd1000 mmap(0x7ffff7dd7000, 16960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7dd7000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fdd000 mmap(