1. 使用单进程、stracegdb调试PHP错误
  2.  
  3. PHP一般是在FPM的呵护下运行的,但是某些情况下进程异常崩溃会导致502。下面是解决思想:

  4. 1. 单进程运行:
  1. php -d display_errors=1 -S 0.0.0.0:88 #然后访问,会直接显示fatal or error的信息
  1. 2. 以上不能解决,则采用strace
  1. strace -d -f -ff -o trace.log -p FPM_ID
  2. #或者:
  3. strace -d -p FPM_ID

3. 如果还没解决问题,就得运用gdb (gnu's debug), 举个粟子:

  1.  

最近在灰度测试PHP7的过程中,php-fpm出现间歇性的段错误。系统的错误信息如下:

  1.  
  1. php-fpm[7664]: segfault at 7f6ff4600000 ip 00007f6ff782176f sp 00007fff2e9c2fe8 error 4 in libc-2.12.so[7f6ff7798000+18a000]
  1.  

为了排查出错的原因,我们接下来需要进行调试。由于错误间歇性出现在php-fpm处理请求的过程中,因此,我们需要获取获取Linux的core dumps文件。

  1.  

打开Linux的core dumps

  1.  

一般情况下,Linux默认core dumps是关闭状态。我们可以将其打开并且重定向到我们指定的文件。

  1.  
  1. $ echo '/tmp/coredump-%e.%p' > /proc/sys/kernel/core_pattern
  1.  

core dumps文件支持变量:

  1.  
  1. %% a single % character
  2. %c core file size soft resource limit of crashing process (since
  3. Linux 2.6.24)
  4. %d dump modesame as value returned by prctl(2) PR_GET_DUMPABLE
  5. (since Linux 3.7)
  6. %e executable filename (without path prefix)
  7. %E pathname of executable, with slashes ('/') replaced by
  8. exclamation marks ('!') (since Linux 3.0).
  9. %g (numeric) real GID of dumped process
  10. %h hostname (same as nodename returned by uname(2))
  11. %p PID of dumped process, as seen in the PID namespace in which
  12. the process resides
  13. %P PID of dumped process, as seen in the initial PID namespace
  14. (since Linux 3.12)
  15. %s number of signal causing dump
  16. %t time of dump, expressed as seconds since the Epoch,
  17. 1970-01-01 00:00:00 +0000 (UTC)
  18. %u (numeric) real UID of dumped process
  1.  

这个例子中,我们把错误文件重定向到/tmp目录下。

  1.  

配置php-fpm支持core dumps

  1.  

为了让php-fpm支持core dumps,我们需要打开php-fpm连接池的rlimit_core配置,在配置文件中设置。

  1.  
  1. rlimit_core = unlimited
  1.  

重启php-fpm进程,当SIGSEGV信号量产生时,将会在你指定的core dumps目录产生指定的文件:

  1.  
  1. $ ls /tmp/coredump*
  2. -rw------- 1 user group 220M /tmp/coredump-php-fpm.2393
  1.  

使用gdb读取core dumps文件

  1.  

首先,确认你的机器中正确安装了gdb调试工具(yum install gdb)。然后,你将使用gdb $program-path $coredump-path这样的命令格式调试。由于我们的程序运行在php-fpm,我们将使用以下的命令调试:

  1.  
  1. $ gdb /usr/local/services/php7/sbin/php-fpm core.6054
  2. GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
  3. Copyright (C) 2010 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://g
  5. ...
  6. Core was generated by `php-fpm: pool www '.
  7. Program terminated with signal 11, Segmentation fault.
  8. #0 0x00007f54017dc76f in memcpy () from /lib64/libc.so.6
  9. ...
  10. (gdb) bt
  11. #0 0x00007f54017dc76f in memcpy () from /lib64/libc.so.6
  12. #1 0x00007f53fdf96443 in zend_string_init (execute_data=0x7f53fe416fc0)
  13. at /usr/local/services/php7/include/php/Zend/zend_string.h:159
  14. #2 hp_execute_ex (execute_data=0x7f53fe416fc0)
  15. at /usr/local/src/xhprof-php7/extension/xhprof.c:1476
  16. #3 0x00000000008c28b0 in ZEND_DO_FCALL_SPEC_HANDLER ()
  17. at /data/software/php-7.0.6/Zend/zend_vm_execute.h:800
  18. #4 0x00000000008851cb in execute_ex (ex=Unhandled dwarf expression opcode 0xf3
  19. )
  20. at /data/software/php-7.0.6/Zend/zend_vm_execute.h:414
  1.  

bt命令将会显示core dumps文件的调用栈。到此为止,我们定位到问题出现在/usr/local/src/xhprof-php7/extension/xhprof.c文件在调用memcpy()方法时,出现内存段错误。

  1.  

结语

  1.  

目前PHP7官方并未支持xhprof扩展,为了分析性能,我们安装了第三方编译过的版本。将该扩展从灰度环境中下线,段错误问题就不再出现了。

  1.  

使用单进程、strace、gdb调试PHP错误的更多相关文章

  1. 【转】gdb 调试段错误

    [转]gdb 调试段错误 转自:blog.csdn.net/yangzhu1982/article/details/6318600 开发嵌入式Linux的时候经常会遇到segmentation fau ...

  2. gdb调试段错误及使用

    在编程调试中,经常出现段错误,此时可用gdb调试.具体方法为注册段错误信号处理函数,在处理函数中启动gdb.具体代码如下: void segv_handler(int no) { ]; ]; FILE ...

  3. 使用gdb调试段错误

    [https://blog.csdn.net/xj9120/article/details/91380074] 1.bt 2.frame number 3.一般是内存问题 4.kill

  4. gdb调试的基本使用

    GDB调试 启动程序准备调试 GDB yourpram 或者 先输入GDB 然后输入 file yourpram 然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传 ...

  5. gdb调试(二)

    继续研究gdb相关的调试技巧,话不多说进入正题: 查看运行时数据: 这个上节中已经用过了,这里就不多说了,比较简单 还是有上节中的simple.c例子,不过得稍微做一些修改为了使用这些命令: simp ...

  6. gdb调试入门(下)

    GDB调试主要包括: 1.查看运行时数据 2.程序错误 3.gdb调试逻辑错误 4.gdb调试段错误 5.core文件调试 一.查看运行时数据 1.print 查看变量值 2.ptype 变量: 查看 ...

  7. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  8. 用GDB调试Segmentation 段错误【转】

    本文转载自:http://blog.csdn.net/learnhard/article/details/4879834 调试Linux程序的时候,出现Segmentation Fault是最郁闷的事 ...

  9. nginx源码分析--使用GDB调试(strace、 pstack )

    nginx源码分析--使用GDB调试(strace.  pstack ) http://blog.csdn.net/scdxmoe/article/details/49070577

随机推荐

  1. RHEL自动安装zookeeper的shell脚本

    RHEL自动安装zookeeper的shell脚本 A:本脚本运行的机器,Linux RHEL6 B,C,D,...:待安装zookeeper cluster的机器, Linux RHEL6 首先在脚 ...

  2. Android编译系统中的Kconfig,Makefile,.config编译系统浅析

    在对Android进行编译时,用的就是Linux下的Makefile和Kconfig编译系统,对整个系统进行编译.当然还包括很多配置命令,比如make defconfig, make oldconfi ...

  3. ssh keygen命令实现免密码通信(git库获取操作权限:开发人员添加到git库中,获取操作权限)

    先看两个机器实现免密码登陆通讯: 假设 A 为客户机器,B为目标机: 要达到的目的: A机器ssh登录B机器无需输入密码: 加密方式选 rsa|dsa均可以,默认dsa 做法: 1.登录A机器 2.s ...

  4. HBase中缓存的优先级

    ava代码   // Instantiate priority buckets BlockBucket bucketSingle = new BlockBucket(bytesToFree, bloc ...

  5. 最大的k个数问题

    代码来源: http://blog.csdn.net/v_JULY_v 调整堆为小顶堆的代码片:基本思想就是把孩子节点中大的一个跟父节点交换 void HeapAdjust(int array[], ...

  6. multiset基础学习,可以有重复类型的多重集合容器

    #include <set> #include <iostream> using namespace std; struct Student { char *name; int ...

  7. FCL源码中数组类型的学习及排序函数Sort函数的分析

    Array 是所有数组的基类ArrayList 解决了所有Array 类的缺点    能动态扩容, 但是类型不安全的,而是会有装箱与拆箱的性能开销List<T> 则是解决了ArrayLis ...

  8. linux上搭建ftp服务器

    摘要 vsftpd 是"very secure FTP daemon"的缩写,安全性是它的一个最大的特点.vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行 ...

  9. sort list(给链表排序)

    Sort a linked list in O(n log n) time using constant space complexity. 题目要求使用O(nlogn)时间复杂度,可以考虑使用归并排 ...

  10. CRT 重启Was

    输入用户名.密码登陆以后 # ps -eaf | grep websphere 找到路径 /usr/IBM/WebSphere/AppServer/ 进入/usr/IBM/WebSphere/AppS ...