昨天在远程调试时,刚开始调试的好好的,突然发现返回的结果变成502了,不对呀!刚刚明明是200的呀!然后我重启了nginx和php-fpm,还是一样的502,难道是代码又有bug了。看了下php-fpm的日志,发现没有任何的出错记录,调试时就是直接断掉,返回个502,什么原因呢?
这时请教了龙哥,在服务器端跟踪php-fpm进程执行时的系统调用和所接收的信号。
首先把php-fpm的进程数量设置为1个,这样就找到是哪个进程处理了cgi请求。
设置好后重启php-fpm服务。
重启后找出那个php-fpm进程的进程号。
然后用gdb调试这个进程。
这时先不设置断点,让程序在IDE中直接一步一步地运行下去,看是在哪个地方出错了。
在代码出错的那一行设置个断点,下次可以直接运行到断点处。
运行完后,就可以看得到出错的地方,先记下这个出错的函数,下次运行时设置断点需要用到(注意:xdebug的断点和gdb的断点是不同的)。
这时,再看一下php-fpm的进程池,发现原来的那个进程的进程号变了,是因为原本的进程挂掉了,主进程又新开了一个子进程。
在Fillder中replay上次的那个请求,等运行到IDE的断点处,再打开gdb,在gdb中设置断点,输入c继续运行。
在IDE中继续运行,这时程序出错了,在gdb中输入bt查看堆栈
在堆栈里可以看到,在用xdebug调试时,是先运行xdebug扩展模块的代码,再运行了原本的php代码。
我在调试时,设置了一个查看的变量,这个变量在运行到这个方法时是一个对象,而我是以数组的方式来读取的,所以语法是有错误的,所以整个http请求返回了错误。由于这是xdebug的错误,所以不使用xdebug调试来运行代码时,返回的数据是正常的。
在找到问题的原因后,我在别的方法内设置了断点,调试时直接跳过这个方法,虽然还是查看同一个变量,但是没有出错。