什么是strace
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、找出程序在启动时读取的配置文件
[]# strace php >&.ini (, O_RDONLY= 1 (No such file ) (, O_RDONLY=
2、使用strace来跟踪cat查看一个文件做了什么
[root](, "cat""index.php", /27 vars /) 0 brk0= (, , |, |, 10= (, ) -ENOENT No such file ) open"/etc/ld.so.cache"O_RDONLYO_CLOEXEC= (, =|, st_size106900..) 0 mmapNULL106900PROT_READMAP_PRIVATE30= () 0 open"/usr/lib64/libc.so.6"O_RDONLYO_CLOEXEC= (, ..832= (, =|, st_size2107768..) 0 mmapNULL3932736PROT_READPROT_EXECMAP_PRIVATEMAP_DENYWRITE30= (, , ) 0 mmap0x7ffff7dd100024576PROT_READPROT_WRITEMAP_PRIVATEMAP_FIXEDMAP_DENYWRITE30x1b6000= (, , |, ||, 10= () 0 mmapNULL4096PROT_READPROT_WRITEMAP_PRIVATEMAP_ANONYMOUS-, ) 0x7ffff7fdd000 mmapNULL8192PROT_READPROT_WRITEMAP_PRIVATEMAP_ANONYMOUS-, ) 0x7ffff7fdb000 arch_prctlARCH_SET_FS0x7ffff7fdb740= (, , ) 0 mprotect0x60b0004096PROT_READ= (, , ) 0 munmap0x7ffff7fde000106900= () 0x60d000 brk0x62e000= () 0x62e000 open"/usr/lib/locale/locale-archive"O_RDONLYO_CLOEXEC= (, =|, st_size106065056..) 0 mmapNULL106065056PROT_READMAP_PRIVATE30= () 0 fstat1{st_modeS_IFCHR0620=makedev1363, .}= (, ) 3 fstat3{st_modeS_IFREG0644=, .}= (, , , ) 0 read3"<?php\nphpinfo();\n"65536= (, , <(; = (, , ) 0 close3= () 0 close2= () ? + exited with ++
跟踪read函数
统计每一系统调用的所执行的时间,次数和出错的次数
[root@localhost mau-c cat index<phpinfo)% time seconds usecs---- ----- ----- --------- -------- 0.000016 8 mmap 0.000011 4 open 0.000009 4 mprotect 0.000007 1 write 0.000007 6 close 0.000005 5 fstat 0.000005 1 munmap 0.000004 3 read 0.000003 4 brk 0.000002 1 2.78 2 1.39 1 0.00 0 ---- ----- ----- --------- -------- 0.000072 1 total
显示每一调用所耗的时间
3、为什么这个程序不能打开我的文件?
当我们开发了一个PHP扩展,可以PHP为什么加载不到我们的扩展文件,通过命令:
[root@localhost mau-e open php >1
在输出的结果中查找失败的open()或access()系统调用,很有可能是因为权限问题导致的。
4、查看程序在干什么
[root@localhost system-p $pid Process futex0x13517c4, , ) -(Resource temporarily unavailablefutex0x13517c4, , ) 0 (, FUTEX_WAKE_PRIVATE1= setsockopt39, SO_KEEPALIVE[]4= sendto39"J\0\0\0\n5.6.30\0\35\7\4\0j;'O<{xh\0\377\367\10\2\0\177\200"., , MSG_DONTWAITNULL0= recvfrom39"\263\0\0\1"4, , ) 4 (, ..179, , ) 179 (, F_OK= open"./db_firewall_log/db.opt") -(No such file ) (, , , MSG_DONTWAITNULL0= recvfrom39"\17\0\0\0"4, , ) 4 (, , , MSG_DONTWAITNULLNULL= sendto39"\7\0\0\1\0\0\0\2\0\0\0"11, , ) 11 (, , , MSG_DONTWAITNULLNULL= recvfrom39"\3set autocommit=0"17, , ) 17
5、为什么****不能连接到该服务器?
[root@localhost mau# strace -e poll,select,connect,recvfrom,sendto ssh root@172.16.1.137 connect3{sa_family, sun_path"/var/run/nscd/socket", ) -(No such or directory(, =AF_LOCAL=}110= 1 ENOENT file ) poll[=, events}, , ) 1 [=, revents}) connect3{sa_family, sun_path"/var/run/nscd/socket", ) -(No such or directory(, =AF_LOCAL=}110= 1 ENOENT file ) sendto3"\24\0\0\0\26\0\1\3\3537\365Z\0\0\0\0\0\0\0\0"200{sa_family, pid0=}12= (, =AF_LOCAL=}110= 1 ENOENT file ) connect3{sa_family, sin_port()=inet_addr"172.16.1.137"}16= 1 ETIMEDOUT ) ssh172.16.137 port : Connection timed out +with ++
strace调试php
[root@localhost mau-ff .log -F /Data/php7/php-c /apps/etc-fpm[root@localhost mau.php0