x86/ARM 设备上的信号 7 与SIGBUS
(参见:)有关man 7 signal
,表示总线错误(内存访问错误)。
总线错误是由硬件引发的故障,它通知操作系统 (OS) 进程正在尝试访问 CPU 无法物理寻址的内存:地址总线的地址无效,因此得名。在大多数架构的现代使用中,这些比分段错误要少得多,分段错误主要是由于内存访问违规:逻辑地址或权限问题。
请参阅:在 x86 Linux 上调试 SIGBUS
可能是错误、Apache 模块错误或硬件问题。
调试
由于Appport在 中生成了崩溃/var/crash/
,因此您可以查看崩溃文件以获取更多详细信息。您可以在文本编辑器中打开它,但是核心转储文件以 base64 格式打包。
要解压它,运行:
cd /var/crash
sudo apport-unpack /var/crash/_usr_sbin_apache2.0.crash _unpacked
请参阅:如何从 /var/crash和调试程序崩溃中读取崩溃文件。
然后运行gdb
分析崩溃文件:
gdb $(cat _unpacked/ExecutablePath) _unpacked/CoreDump
然后输入:bt
或bt full
检查堆栈跟踪。
假设您的 Apache 二进制文件没有使用调试符号编译,它不会有太大帮助。但是,您可以确定崩溃发生的位置,例如某些 Apache/PHP 模块,例如:
Program terminated with signal X, ...
#0 0x00007f39a616e09a in ?? () from /usr/lib/apache2/modules/libphp5.so
通过从命令滚动列表来检查你有多少帧bt
,如果有太多,比如超过 1000,潜在的问题是在你的代码应用程序的某个地方存在无限循环。
PHP
如果您的应用程序在 PHP 下运行,使用 进行更高级的调试gdb
,请参阅:如何在 gdb 中获取当前 PHP 函数名?
就像上面的例子一样,libphp5.so
模块是处理 PHP 的主要模块。
要找出它属于哪个包,请运行:
$ dpkg -S /usr/lib/apache2/modules/libphp5.so
libapache2-mod-php5: /usr/lib/apache2/modules/libphp5.so
然后考虑升级故障库/模块。
如果某些 3rd 方模块崩溃,请考虑通过禁用它php5dismod
,例如
$ sudo apachectl -M
Loaded Modules:
...
$ sudo a2dismod somemodule
$ php -m
$ sudo php5dismod somemodule # Optionally.
$ sudo apachectl configtest
Syntax OK
$ sudo service apache2 reload
* Reloading web server config apache2
然后,如果问题仍然存在,请尝试从命令行使用php
. 如果可以,请使用 调试它strace
,例如
$ strace -f php myscript.php
...
gettimeofday({1560725354, 768601}, NULL) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)
然后检查崩溃前 PHP 进程正在执行的最新操作。要增加消息的大小,请使用-s 1500
, 保存到日志文件中,请使用-o file.log
.