lanlin / notes

个人笔记
https://github.com/lanlin/notes/issues
30 stars 0 forks source link

PHP调试工具 or PHP Debug Tools #96

Open lanlin opened 4 years ago

lanlin commented 4 years ago

1 - tcpdump 抓包

在调试网络通信程序是tcpdump是必备工具。 tcpdump很强大,可以看到网络通信的每个细节。 如TCP,可以看到3次握手,PUSH/ACK数据推送,close4次挥手,全部细节。 包括每一次网络收包的字节数,时间等。

sudo tcpdump -i any tcp port 9501

tcpdump需要root权限
需要要看通信的数据内容,可以加 -Xnlps0 参数,其他更多参数请参见网上的文章

运行结果

13:29:07.788802 IP localhost.42333 > localhost.9501: Flags [S], seq 828582357, win 43690, options [mss 65495,sackOK,TS val 2207513 ecr 0,nop,wscale 7], length 0
13:29:07.788815 IP localhost.9501 > localhost.42333: Flags [S.], seq 1242884615, ack 828582358, win 43690, options [mss 65495,sackOK,TS val 2207513 ecr 2207513,nop,wscale 7], length 0
13:29:07.788830 IP localhost.42333 > localhost.9501: Flags [.], ack 1, win 342, options [nop,nop,TS val 2207513 ecr 2207513], length 0
13:29:10.298686 IP localhost.42333 > localhost.9501: Flags [P.], seq 1:5, ack 1, win 342, options [nop,nop,TS val 2208141 ecr 2207513], length 4
13:29:10.298708 IP localhost.9501 > localhost.42333: Flags [.], ack 5, win 342, options [nop,nop,TS val 2208141 ecr 2208141], length 0
13:29:10.298795 IP localhost.9501 > localhost.42333: Flags [P.], seq 1:13, ack 5, win 342, options [nop,nop,TS val 2208141 ecr 2208141], length 12
13:29:10.298803 IP localhost.42333 > localhost.9501: Flags [.], ack 13, win 342, options [nop,nop,TS val 2208141 ecr 2208141], length 0
13:29:11.563361 IP localhost.42333 > localhost.9501: Flags [F.], seq 5, ack 13, win 342, options [nop,nop,TS val 2208457 ecr 2208141], length 0
13:29:11.563450 IP localhost.9501 > localhost.42333: Flags [F.], seq 13, ack 6, win 342, options [nop,nop,TS val 2208457 ecr 2208457], length 0
13:29:11.563473 IP localhost.42333 > localhost.9501: Flags [.], ack 14, win 342, options [nop,nop,TS val 2208457 ecr 2208457], length 0
lanlin commented 4 years ago

2 - strace 跟踪系统调用

strace可以跟踪系统调用的执行情况,在程序发生问题后,可以用strace分析和跟踪问题。

strace -d -f -p $PID                           // 跟踪执行并将结果直接输出到屏幕
strace -o /tmp/strace.log -f -p $PID           // 跟踪执行并将结果记录到strace.log

FreeBSD/MacOS下可以使用 dtruss

dtruss -a -f -p $PID
lanlin commented 4 years ago

3 - gdb 调试

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,可以用来调试C/C++开发的程序,PHP是使用C语言开发的,所以可以用GDB来调试PHP程序。

gdb调试是命令行交互式的,需要掌握常用的指令。

使用方法

gdb -p 进程ID
gdb php
gdb php core

gdb有3种使用方式:

如果 PATH 环境变量中没有 php,gdb 时需要指定绝对路径,如 gdb /usr/local/bin/php

  1. 开启 coredump #83

    ulimit -c unlimited
  2. for OSX

    lldb --core "/cores/core.xxxxx"
    (lldb) bt all
  3. for Linux

    gdb php -c core.xxxxx
    (gdb) bt

常用指令

zbacktrace

zbacktrace是PHP源码包提供的一个gdb自定义指令,功能与bt指令类似,与bt不同的是zbacktrace看到的调用栈是PHP函数调用栈,而不是C函数。

下载 .gbdinit 文件,地址为 https://raw.githubusercontent.com/php/php-src/PHP-8.0.0/.gdbinit 注意 PHP 版本号一定要与你正在使用的版本完全一致,然后在 gdb shell 中输入

(gdb) source /path/to/your/.gdbinit
(gdb) zbacktrace

.gdbinit还提供了其他更多指令,可以查看源码了解详细的信息 #99。

使用gdb+zbacktrace跟踪死循环问题

gdb -p 进程ID
lanlin commented 4 years ago

4 - lsof 跟踪句柄

Linux平台提供了lsof工具可以查看某个进程打开的文件句柄。可以用于跟踪PHP工作进程所有打开的socket、file、资源。

使用方法

lsof -p [进程ID]

运行结果

lsof -p 26821
lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing
      Output information may be incomplete.
COMMAND   PID USER   FD      TYPE             DEVICE SIZE/OFF    NODE NAME
php     26821  htf  cwd       DIR                8,4     4096 5375979 /home/htf/workspace/swoole/examples
php     26821  htf  rtd       DIR                8,4     4096       2 /
php     26821  htf  txt       REG                8,4 24192400 6160666 /opt/php/php-5.6/bin/php
php     26821  htf  DEL       REG                0,5          7204965 /dev/zero
php     26821  htf  DEL       REG                0,5          7204960 /dev/zero
php     26821  htf  DEL       REG                0,5          7204958 /dev/zero
php     26821  htf  DEL       REG                0,5          7204957 /dev/zero
php     26821  htf  DEL       REG                0,5          7204945 /dev/zero
php     26821  htf  mem       REG                8,4   761912 6160770 /opt/php/php-5.6/lib/php/extensions/debug-zts-20131226/gd.so
php     26821  htf  mem       REG                8,4  2769230 2757968 /usr/local/lib/libcrypto.so.1.1
php     26821  htf  mem       REG                8,4   162632 6322346 /lib/x86_64-linux-gnu/ld-2.23.so
php     26821  htf  DEL       REG                0,5          7204959 /dev/zero
php     26821  htf    0u      CHR             136,20      0t0      23 /dev/pts/20
php     26821  htf    1u      CHR             136,20      0t0      23 /dev/pts/20
php     26821  htf    2u      CHR             136,20      0t0      23 /dev/pts/20
php     26821  htf    3r      CHR                1,9      0t0      11 /dev/urandom
php     26821  htf    4u     IPv4            7204948      0t0     TCP *:9501 (LISTEN)
php     26821  htf    5u     IPv4            7204949      0t0     UDP *:9502 
php     26821  htf    6u     IPv6            7204950      0t0     TCP *:9503 (LISTEN)
php     26821  htf    7u     IPv6            7204951      0t0     UDP *:9504 
php     26821  htf    8u     IPv4            7204952      0t0     TCP localhost:8000 (LISTEN)
php     26821  htf    9u     unix 0x0000000000000000      0t0 7204953 type=DGRAM
php     26821  htf   10u     unix 0x0000000000000000      0t0 7204954 type=DGRAM
php     26821  htf   11u     unix 0x0000000000000000      0t0 7204955 type=DGRAM
php     26821  htf   12u     unix 0x0000000000000000      0t0 7204956 type=DGRAM
php     26821  htf   13u  a_inode               0,11        0    9043 [eventfd]
php     26821  htf   14u     unix 0x0000000000000000      0t0 7204961 type=DGRAM
php     26821  htf   15u     unix 0x0000000000000000      0t0 7204962 type=DGRAM
php     26821  htf   16u     unix 0x0000000000000000      0t0 7204963 type=DGRAM
php     26821  htf   17u     unix 0x0000000000000000      0t0 7204964 type=DGRAM
php     26821  htf   18u  a_inode               0,11        0    9043 [eventpoll]
php     26821  htf   19u  a_inode               0,11        0    9043 [signalfd]
php     26821  htf   20u  a_inode               0,11        0    9043 [eventpoll]
php     26821  htf   22u     IPv4            7452776      0t0     TCP localhost:9501->localhost:59056 (ESTABLISHED)

列表信息简要解读

其中 FD 表示文件描述符,应用程序通过文件描述符识别该文件

描述符 说明
cwd 应用程序的当前工作目录,这是该应用程序启动的目录
txt 该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如 /sbin/init 程序
lnn library references (AIX)
er FD information error (see NAME column)
jld jail directory (FreeBSD)
ltx shared library text (code and data)
mxx hex memory-mapped type number xx
m86 DOS Merge mapped file
mem memory-mapped file
mmap memory-mapped device
pd parent directory
rtd root directory
tr kernel trace file (OpenBSD)
v86 VP/ix mapped file
0 表示标准输出
1 表示标准输入
2 表示标准错误
数字 表示其他文件句柄值

FD中数字后面出现的字母为文件锁类型

文件锁 说明
N 用于未知类型的 Solaris NFS 锁
r 对文件局部进行读取锁定
R 对整个文件进行读取锁定
w 对文件局部进行写入锁定
W 对整个文件进行写入锁定
u 任意长度的读写锁
U 用于未知类型的锁
x 锁定 SCO OpenServer Xenix 文件局部
X 锁定 SCO OpenServer Xenix 文件整体
空格 不存在任何锁
lanlin commented 4 years ago

5 - perf 性能跟踪

perf工具是Linux内核提供一个非常强大的动态跟踪工具,perf top指令可用于实时分析正在执行程序的性能问题。与callgrindxdebugxhprof等工具不同,perf无需修改代码导出profile结果文件。

使用方法

perf top -p [进程ID]

输出结果

perf

perf结果中清楚地展示了当前进程运行时各个C函数的执行耗时,可以了解哪个C函数占用CPU资源较多。

如果你熟悉Zend VM,某些Zend函数调用过多,可以说明你的程序中大量使用了某些函数,导致CPU占用过高,针对性的进行优化。