使用strace来查找php的坑

一段废话

之前的shell分享中提到过strace这个流弊的工具,当时也是用linux C的代码造了一个场景来演示,而今再使用php构造一个场景来演示下如何查找一些坑,尽管差异不是很大

问题

先看下问题,最后会描述下构造的问题,问题如下

[root@c488ca153abc xiaoju]# php7/bin/php strace.php &

执行了一个php脚本,没有按照预期时间内返回,目测是阻塞住了

查问题

首先查pid

[root@c488ca153abc xiaoju]# ps aux | grep strace.php
root     12052  0.0  0.0 222344 10816 pts/0    S    18:15   0:00 php7/bin/php strace.php

通过strace看下12052进程的系统调用的阻塞情况

[root@c488ca153abc ~]# strace -p 12052
Process 12052 attached
wait4(-1,

可以看到当前阻塞在wait4,该系统调用会挂起当前进程,等待指定的子进程状态改变,其中参数是-1表示等待任一子进程的返回,如此我们去查看下12052下面的子进程

[root@c488ca153abc ~]# pstree -p 12052
php(12052)───php(12053)

继续使用strace看看12503为什么死也不返回

[root@c488ca153abc ~]# strace -p 12053
Process 12053 attached
flock(3, LOCK_EX

好吧,是flock文件锁,还是排他锁,文件描述符是3,看下对应的文件名是啥
可以通过lsof看,也可以通过/proc/12053/fd目录查看,该文件包含进程打开文件的情况

[root@c488ca153abc fd]# ll
总用量 0
lrwx------ 1 root root 64 11月 21 18:16 0 -> /dev/pts/0
lrwx------ 1 root root 64 11月 21 18:16 1 -> /dev/pts/0
lrwx------ 1 root root 64 11月 21 18:16 2 -> /dev/pts/0
lrwx------ 1 root root 64 11月 21 18:16 3 -> /home/xiaoju/lock
lrwx------ 1 root root 64 11月 21 18:16 5 -> socket:[2333709193]

倒数第三列就是文件描述符,3 -> /home/xiaoju/lock,找到12053心心念念的文件了,看下是谁占用了这个文件

[root@c488ca153abc fd]# lsof /home/xiaoju/lock | grep -v 12053
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
php     12052 root    3uW  REG  253,6        0 17725454 /home/xiaoju/lock

至此,可以断定是一个'死锁'了,父进程锁着文件等待子进程返回,子进程一直在等待父进程释放文件锁,如果还要进一步确定,可以到/proc/12052/目录中看到更多详细的信息,这里不赘述.

构造问题

构造了一个如下的问题,使用pcntl_fork建立一个父子进程,父子进程同时打开一个文件(内核级别会是两个不同的句柄),父进程先锁住A文件,然后开始pcntl_wait等待子进程的返回,最后释放锁,子进程以阻塞模式去获取文件锁,造成一个双等待的阻塞,如下是php的代码

你可能感兴趣的:(使用strace来查找php的坑)