如何诊断此 PHP 分段错误?
Posted
技术标签:
【中文标题】如何诊断此 PHP 分段错误?【英文标题】:How do I diagnose this PHP segmentation fault? 【发布时间】:2012-10-16 06:45:24 【问题描述】:我正在运行导致分段错误的命令行 php 作业。这项工作已经工作了很长时间,但它处理的是通过电子邮件发送的内容。显然这封电子邮件中有一些东西破坏了它,但我不知道是什么。如果我把core文件放到gdb里,真的没用:
$ gdb /usr/local/bin/php core.20381
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/bin/php...done.
[New Thread 20381]
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libcrypt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /usr/lib/libmysqlclient_r.so.15...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libmysqlclient_r.so.15
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libz.so.1
Reading symbols from /usr/lib/libmcrypt.so.4...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libmcrypt.so.4
Reading symbols from /usr/lib/libltdl.so.7...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libltdl.so.7
Reading symbols from /lib/libpng12.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libpng12.so.0
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libnsl.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /usr/lib/libcurl-gnutls.so.4...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libcurl-gnutls.so.4
Reading symbols from /usr/lib/libxml2.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libxml2.so.2
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libresolv.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libresolv.so.2
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /usr/lib/libidn.so.11...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libidn.so.11
Reading symbols from /usr/lib/liblber-2.4.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/liblber-2.4.so.2
Reading symbols from /usr/lib/libldap_r-2.4.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libldap_r-2.4.so.2
Reading symbols from /usr/lib/libgssapi_krb5.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgssapi_krb5.so.2
Reading symbols from /usr/lib/libgnutls.so.26...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgnutls.so.26
Reading symbols from /lib/libgcrypt.so.11...(no debugging symbols found)...done.
Loaded symbols for /lib/libgcrypt.so.11
Reading symbols from /usr/lib/libsasl2.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libsasl2.so.2
Reading symbols from /usr/lib/libkrb5.so.3...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libkrb5.so.3
Reading symbols from /usr/lib/libk5crypto.so.3...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libk5crypto.so.3
Reading symbols from /lib/libcom_err.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libcom_err.so.2
Reading symbols from /usr/lib/libkrb5support.so.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libkrb5support.so.0
Reading symbols from /lib/libkeyutils.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libkeyutils.so.1
Reading symbols from /usr/lib/libtasn1.so.3...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libtasn1.so.3
Reading symbols from /lib/libgpg-error.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libgpg-error.so.0
Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libnss_files.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libnss_files.so.2
Can't read symbols from system-supplied DSO at 0x7fffb4bfc000: File truncated
Core was generated by `/usr/local/bin/php /src/prod/current/utils/cron.php --run=/utils/proces'.
Program terminated with signal 11, Segmentation fault.
#0 match (
eptr=0x1370a887 "/td>\n\t\t\t\t\t\t\n\t\t\t\t\t</tr>\n\t\t\t\t\t\n\t\t\t\t</table>\n\t\t\t</td>\n\t\t</tr>\n\t\t\n\t\t<tr>\n\t\t\t<td style=\"border-top:3px solid #efefef; padding:20px 10px;\">\n\t\t\t\t<table style=\"width:100%;\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t\n", '\t' <repeats 12 times>, "\n\t\t\t\t"..., ecode=0x133dc3aa "N",
mstart=0x13708600 "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n\n</head>\n\n<body style=\"padding"..., markptr=0x0, offset_top=4, md=0x7fffb4b1b620, ims=0, eptrb=0x0, flags=0, rdepth=17680) at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:470
470
如果我做一个“bt”,我只会一遍又一遍地得到这个“匹配”语句。以下是前几个:
#1 0x000000000046ef1e in match (
eptr=0x1370a887 "/td>\n\t\t\t\t\t\t\n\t\t\t\t\t</tr>\n\t\t\t\t\t\n\t\t\t\t</table>\n\t\t\t</td>\n\t\t</tr>\n\t\t\n\t\t<tr>\n\t\t\t<td style=\"border-top:3px solid #efefef; padding:20px 10px;\">\n\t\t\t\t<table style=\"width:100%;\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t\n", '\t' <repeats 12 times>, "\n\t\t\t\t"..., ecode=0x133dc3a5 "_", mstart=<value optimized out>, markptr=<value optimized out>,
offset_top=<value optimized out>, md=0x7fffb4b1b620, ims=0, eptrb=0x0, flags=0, rdepth=17679) at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:803
#2 0x0000000000479789 in match (
eptr=0x1370a887 "/td>\n\t\t\t\t\t\t\n\t\t\t\t\t</tr>\n\t\t\t\t\t\n\t\t\t\t</table>\n\t\t\t</td>\n\t\t</tr>\n\t\t\n\t\t<tr>\n\t\t\t<td style=\"border-top:3px solid #efefef; padding:20px 10px;\">\n\t\t\t\t<table style=\"width:100%;\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t\n", '\t' <repeats 12 times>, "\n\t\t\t\t"..., ecode=0x133dc5ca "V\002%\033U\002.", mstart=<value optimized out>,
markptr=<value optimized out>, offset_top=<value optimized out>, md=0x7fffb4b1b620, ims=0, eptrb=0x0, flags=0, rdepth=<value optimized out>)
at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:1623
#3 0x000000000046ef1e in match (
eptr=0x1370a886 "</td>\n\t\t\t\t\t\t\n\t\t\t\t\t</tr>\n\t\t\t\t\t\n\t\t\t\t</table>\n\t\t\t</td>\n\t\t</tr>\n\t\t\n\t\t<tr>\n\t\t\t<td style=\"border-top:3px solid #efefef; padding:20px 10px;\">\n\t\t\t\t<table style=\"width:100%;\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t\n", '\t' <repeats 12 times>, "\n\t\t\t"..., ecode=0x133dc3a5 "_", mstart=<value optimized out>, markptr=<value optimized out>,
offset_top=<value optimized out>, md=0x7fffb4b1b620, ims=0, eptrb=0x0, flags=0, rdepth=17677) at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:803
#4 0x0000000000479789 in match (
eptr=0x1370a886 "</td>\n\t\t\t\t\t\t\n\t\t\t\t\t</tr>\n\t\t\t\t\t\n\t\t\t\t</table>\n\t\t\t</td>\n\t\t</tr>\n\t\t\n\t\t<tr>\n\t\t\t<td style=\"border-top:3px solid #efefef; padding:20px 10px;\">\n\t\t\t\t<table style=\"width:100%;\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t\n", '\t' <repeats 12 times>, "\n\t\t\t"..., ecode=0x133dc5ca "V\002%\033U\002.", mstart=<value optimized out>,
markptr=<value optimized out>, offset_top=<value optimized out>, md=0x7fffb4b1b620, ims=0, eptrb=0x0, flags=0, rdepth=<value optimized out>)
at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:1623
#5 0x000000000046ef1e in match (
eptr=0x1370a885 "\t</td>\n\t\t\t\t\t\t\n\t\t\t\t\t</tr>\n\t\t\t\t\t\n\t\t\t\t</table>\n\t\t\t</td>\n\t\t</tr>\n\t\t\n\t\t<tr>\n\t\t\t<td style=\"border-top:3px solid #efefef; padding:20px 10px;\">\n\t\t\t\t<table style=\"width:100%;\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t\n", '\t' <repeats 12 times>, "\n\t\t"..., ecode=0x133dc3a5 "_", mstart=<value optimized out>, markptr=<value optimized out>,
offset_top=<value optimized out>, md=0x7fffb4b1b620, ims=0, eptrb=0x0, flags=0, rdepth=17675) at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:803
我真的很茫然。我试过在 strace 中运行该命令,它似乎在 PEAR Mail_Queue 库中出现了段错误。这是 strace 的结尾(一些识别信息已被删除):
lstat("/src/prod/releases/20121025202143/www/application/pear/MDB2/Driver/mysql.php", st_mode=S_IFREG|0770, st_size=55723, ...) = 0
lstat("/src/prod/releases/20121025202143/www/application/pear/MDB2/Driver", st_mode=S_IFDIR|0770, st_size=4096, ...) = 0
lstat("/src/prod/releases/20121025202143/www/application/pear/MDB2", st_mode=S_IFDIR|0770, st_size=4096, ...) = 0
lstat("/src/prod/releases/20121025202143/www/application/pear", st_mode=S_IFDIR|0770, st_size=4096, ...) = 0
open("/src/prod/releases/20121025202143/www/application/pear/MDB2/Driver/mysql.php", O_RDONLY) = 6
fstat(6, st_mode=S_IFREG|0770, st_size=55723, ...) = 0
fstat(6, st_mode=S_IFREG|0770, st_size=55723, ...) = 0
fstat(6, st_mode=S_IFREG|0770, st_size=55723, ...) = 0
mmap(NULL, 55723, PROT_READ, MAP_SHARED, 6, 0) = 0x2b49f7bb4000
brk(0x987b000) = 0x987b000
brk(0x98bb000) = 0x98bb000
munmap(0x2b49f7bb4000, 55723) = 0
close(6) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 6
fcntl(6, F_SETFL, O_RDONLY) = 0
fcntl(6, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(6, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(6, sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("IP ADDRESS TO DB SERVER REMOVED"), 16) = -1 EINPROGRESS (Operation now in progress)
fcntl(6, F_SETFL, O_RDWR) = 0
poll([fd=6, events=POLLIN|POLLPRI], 1, 60000) = 1 ([fd=6, revents=POLLIN])
setsockopt(6, SOL_SOCKET, SO_RCVTIMEO, "\2003\341\1\0\0\0\0\0\0\0\0\0\0\0\0", 16) = 0
setsockopt(6, SOL_SOCKET, SO_SNDTIMEO, "\2003\341\1\0\0\0\0\0\0\0\0\0\0\0\0", 16) = 0
setsockopt(6, SOL_IP, IP_TOS, [8], 4) = 0
setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(6, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
poll([fd=6, events=POLLIN], 1, 60000) = 1 ([fd=6, revents=POLLIN])
read(6, "C\0\0\0\n5.1.37-1ubuntu5.5-log\0Q\257\3\0009"..., 16384) = 71
write(6, "=\0\0\1\205\242\2\0\0\0\0@\10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65) = 65
read(6, "\7\0\0\2\0\0\0\2\0\0\0", 16384) = 11
poll([fd=6, events=POLLIN|POLLPRI], 1, 0) = 0 (Timeout)
write(6, "\10\0\0\0\2xxxxx", 12) = 12
read(6, "\7\0\0\1\0\0\0\2\0\0\0", 16384) = 11
lstat("/src/prod/current/www/application/pear/Mail/mime.php", st_mode=S_IFREG|0770, st_size=50252, ...) = 0
lstat("/src/prod/current/www/application/pear/Mail", st_mode=S_IFDIR|0770, st_size=4096, ...) = 0
lstat("/src/prod/current/www/application/pear", st_mode=S_IFDIR|0770, st_size=4096, ...) = 0
lstat("/src/prod/current/www/application", st_mode=S_IFDIR|0776, st_size=4096, ...) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault
如果有人对调查路线有任何想法或指示,我将不胜感激。我真的被这个难住了。
【问题讨论】:
看起来像preg_match
中的 ***,可能是由真正的病态输入引起的。您可以尝试找出导致问题的脚本的哪一行,然后确定函数的输入是什么,然后提交 PHP 错误报告 :)
您解决了这个问题吗?看起来您正在运行 2010 年 12 月发布的 PHP 5.3.4,您是否尝试更新到更新的版本?
【参考方案1】:
如果遇到段错误,我通常会使用 xdebug。我更喜欢使用以下行:
php -d xdebug.auto_trace=ON -d xdebug.trace_output_dir=mytracedir/ myscript.php
使用 mytracedir/ 下的跟踪输出,您可以轻松找出大概的 php 行,这会破坏脚本。然后在每行一个语句中重写该行并使用error_log()
调试变量。如果你使用__destruct()
或__toString()
,它可能会变得更棘手。
更多信息请参见here。
(如果扩展未加载,但已安装,请尝试添加php -dzend_extension=xdebug.so [...]
)
【讨论】:
这也会崩溃。尽管它是一个不错的工具;) 是的,但是您可以看到 php 进程在崩溃之前走了多远。如果您有多个可能的行崩溃(PCRE 递归),则您有更好的机会找到正确的行。至少,我会那样做;-) 对,好点。你也可以通过 xdebug 和远程调试来做到这一点。应该可以在 GDB 中启动会话。 +1。【参考方案2】:调试器已经告诉你发生了什么:
... rdepth=17680) at /home/farmer/srcs/php-5.3.4/ext/pcre/pcrelib/pcre_exec.c:470
见pcre.recursion_limit setting:
pcre.recursion_limit - PCRE 的递归限制。请注意,如果您将此值设置为较大的数字,您可能会消耗所有可用的进程堆栈并最终导致 PHP 崩溃(由于达到操作系统施加的堆栈大小限制)。
降低它的值,这样它就不会因为快速修复而崩溃。然后你会看到你的 HTML 没有被正则表达式完全处理。
改进表达式不那么依赖递归。您可能只想使用 HTML 解析器。
【讨论】:
【参考方案3】:尝试删除memcache.so
并从命令行php.ini
禁用opcache,包括opcache 部分注释。
发布运行带有-c path/php.cli.ini
和-d memory_limit -1
参数的脚本
【讨论】:
【参考方案4】:同样的问题出现在不同的情况下。
我使用 phpstorm 调试 laravel 项目,并在评估表达式时 php 服务器出现故障。
只需打印Segmentation fault: 11
php 版本是 7.3,降级到 7.2。在 Phpstorm 设置中,我也将 php 语言级别设置为 7.2。问题解决了。
希望对某人有所帮助:)
【讨论】:
【参考方案5】:我遇到了这个问题。原来我运行的命令是针对 PHP7.1 的,而在服务器上是 PHP7.3。
一旦我像/usr/bin/php71
一样运行它们,它们就会毫无问题地执行。
希望对某人有所帮助:)
【讨论】:
以上是关于如何诊断此 PHP 分段错误?的主要内容,如果未能解决你的问题,请参考以下文章