使用单进程、strace、gdb调试PHP错误
使用单进程、strace、gdb调试PHP错误 PHP一般是在FPM的呵护下运行的,但是某些情况下进程异常崩溃会导致502。下面是解决思想:
1. 单进程运行:
php -d display_errors=1 -S 0.0.0.0:88 #然后访问,会直接显示fatal or error的信息
2. 以上不能解决,则采用strace
strace -d -f -ff -o trace.log -p FPM_ID
#或者:
strace -d -p FPM_ID
3. 如果还没解决问题,就得运用gdb (gnu's debug), 举个粟子:
最近在灰度测试PHP7的过程中,php-fpm出现间歇性的段错误。系统的错误信息如下:
php-fpm[7664]: segfault at 7f6ff4600000 ip 00007f6ff782176f sp 00007fff2e9c2fe8 error 4 in libc-2.12.so[7f6ff7798000+18a000]
为了排查出错的原因,我们接下来需要进行调试。由于错误间歇性出现在php-fpm处理请求的过程中,因此,我们需要获取获取Linux的core dumps文件。
打开Linux的core dumps
一般情况下,Linux默认core dumps是关闭状态。我们可以将其打开并且重定向到我们指定的文件。
$ echo '/tmp/coredump-%e.%p' > /proc/sys/kernel/core_pattern
core dumps文件支持变量:
%% a single % character
%c core file size soft resource limit of crashing process (since
Linux 2.6.24)
%d dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE
(since Linux 3.7)
%e executable filename (without path prefix)
%E pathname of executable, with slashes ('/') replaced by
exclamation marks ('!') (since Linux 3.0).
%g (numeric) real GID of dumped process
%h hostname (same as nodename returned by uname(2))
%p PID of dumped process, as seen in the PID namespace in which
the process resides
%P PID of dumped process, as seen in the initial PID namespace
(since Linux 3.12)
%s number of signal causing dump
%t time of dump, expressed as seconds since the Epoch,
1970-01-01 00:00:00 +0000 (UTC)
%u (numeric) real UID of dumped process
这个例子中,我们把错误文件重定向到/tmp
目录下。
配置php-fpm支持core dumps
为了让php-fpm支持core dumps,我们需要打开php-fpm连接池的rlimit_core
配置,在配置文件中设置。
rlimit_core = unlimited
重启php-fpm进程,当SIGSEGV
信号量产生时,将会在你指定的core dumps目录产生指定的文件:
$ ls /tmp/coredump*
-rw------- 1 user group 220M /tmp/coredump-php-fpm.2393
使用gdb读取core dumps文件
首先,确认你的机器中正确安装了gdb调试工具(yum install gdb
)。然后,你将使用gdb $program-path $coredump-path
这样的命令格式调试。由于我们的程序运行在php-fpm,我们将使用以下的命令调试:
$ gdb /usr/local/services/php7/sbin/php-fpm core.6054
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://g
...
Core was generated by `php-fpm: pool www '.
Program terminated with signal 11, Segmentation fault.
#0 0x00007f54017dc76f in memcpy () from /lib64/libc.so.6
...
(gdb) bt
#0 0x00007f54017dc76f in memcpy () from /lib64/libc.so.6
#1 0x00007f53fdf96443 in zend_string_init (execute_data=0x7f53fe416fc0)
at /usr/local/services/php7/include/php/Zend/zend_string.h:159
#2 hp_execute_ex (execute_data=0x7f53fe416fc0)
at /usr/local/src/xhprof-php7/extension/xhprof.c:1476
#3 0x00000000008c28b0 in ZEND_DO_FCALL_SPEC_HANDLER ()
at /data/software/php-7.0.6/Zend/zend_vm_execute.h:800
#4 0x00000000008851cb in execute_ex (ex=Unhandled dwarf expression opcode 0xf3
)
at /data/software/php-7.0.6/Zend/zend_vm_execute.h:414
bt
命令将会显示core dumps文件的调用栈。到此为止,我们定位到问题出现在/usr/local/src/xhprof-php7/extension/xhprof.c
文件在调用memcpy()
方法时,出现内存段错误。
结语
目前PHP7官方并未支持xhprof
扩展,为了分析性能,我们安装了第三方编译过的版本。将该扩展从灰度环境中下线,段错误问题就不再出现了。
使用单进程、strace、gdb调试PHP错误的更多相关文章
- 【转】gdb 调试段错误
[转]gdb 调试段错误 转自:blog.csdn.net/yangzhu1982/article/details/6318600 开发嵌入式Linux的时候经常会遇到segmentation fau ...
- gdb调试段错误及使用
在编程调试中,经常出现段错误,此时可用gdb调试.具体方法为注册段错误信号处理函数,在处理函数中启动gdb.具体代码如下: void segv_handler(int no) { ]; ]; FILE ...
- 使用gdb调试段错误
[https://blog.csdn.net/xj9120/article/details/91380074] 1.bt 2.frame number 3.一般是内存问题 4.kill
- gdb调试的基本使用
GDB调试 启动程序准备调试 GDB yourpram 或者 先输入GDB 然后输入 file yourpram 然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传 ...
- gdb调试(二)
继续研究gdb相关的调试技巧,话不多说进入正题: 查看运行时数据: 这个上节中已经用过了,这里就不多说了,比较简单 还是有上节中的simple.c例子,不过得稍微做一些修改为了使用这些命令: simp ...
- gdb调试入门(下)
GDB调试主要包括: 1.查看运行时数据 2.程序错误 3.gdb调试逻辑错误 4.gdb调试段错误 5.core文件调试 一.查看运行时数据 1.print 查看变量值 2.ptype 变量: 查看 ...
- gdb调试PHP扩展错误
有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...
- 用GDB调试Segmentation 段错误【转】
本文转载自:http://blog.csdn.net/learnhard/article/details/4879834 调试Linux程序的时候,出现Segmentation Fault是最郁闷的事 ...
- nginx源码分析--使用GDB调试(strace、 pstack )
nginx源码分析--使用GDB调试(strace. pstack ) http://blog.csdn.net/scdxmoe/article/details/49070577
随机推荐
- java自带dom工具使用实例
代码参考自 黄亿华大神的<<1000行代码读懂Spring(一)- 实现一个基本的IoC容器>> 原网页如下 http://my.oschina.net/flashsword/ ...
- iOSAPP启动效果复杂动画之抽丝剥茧
一.前言 随着开发者的增多和时间的累积,AppStore已经有非常多的应用了,每年都有很多新的APP产生.但是我们手机上留存的应用有限,所以如何吸引用户,成为产品设计的一项重要内容.其中炫酷的动画效果 ...
- android 向webview传值
android中可以使用WebView加载网页,同时Android端的java代码可以与网页上的javascript代码之间相互调用. 效果图: (一)Android部分: 布局代码: <spa ...
- 嵌入式C语言位运算之清位置位
如题,在嵌入式开发中,掌握位运算是节省开发时间和提高开发效率的一种高效方式. 我们不得不去熟悉如何快速掌握位运算这种高效的技巧,接下来看看程序.. #include <stdio.h> # ...
- C++语言之析构函数与构造函数
#include <iostream> using namespace std ; class Dog { //默认情况下定义变量为私有 int a ; public: //两个函数都只能 ...
- 使用XStream是实现XML与Java对象的转换(3)--注解
六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...
- OOP的基本原则
OOP的基本原则 点击打开链接
- left join 原理分析
left join 原理分析 [转贴 2006-11-15 16:19:50] 字号:大 中 小 案例分析 user表: id | name --------- 1 | libk ...
- Gradle初探
(一):创建一个Gradle项目 1. 环境准备 1.1. 先上Gradle官网下载最新版的程序,地址:https://gradle.org/gradle-download/. 1.2. 配置环境变量 ...
- Appium-Desktop基本安装教程
点击详见我的简书博客 一.下载桌面程序安装包 点击此处下载--Appium Desktop下载地址 此处楼主下载的是1.4.0Windows桌面版的 二.配置好自己的Android环境 环境变量: A ...