什么情况下会出现段错误(Sementation Fault)
当一个程序试图访问不允许它访问的内存区域,或者试图以某种不允许的方式访问内存区域(例如,试图对只读内存区域写入数据,或者试图覆盖操作系统的部分内存),就会触发segmentation fault。
通常信号#11
(SIGSEGV
)在signal.h
文件中做了定义。程序在接收到SIGSEGV
信号的默认动作是异常退出。这个动作将终止进程,但是可能会生成一个core文件(也就是众所周知的core dump
)用于debugging,或者执行一些特定平台相关的动作。一个core dump文件记录了计算机程序在特定事件的工作内存的状态,也就是当程序异常退出时内存中的信息。
Segmentation fault在以下情况发生:
- 存在bug的程序/命令,只能通过补丁来修复
- 在C程序中,当你尝试访问一个数组时候超出了数组的最后边界时候会出现SegFault
- 在chrooted jail环境中,当关键的共享库,配置文件或者
/dev/
对象缺失时候会发生SegFault - 有时候硬件或者故障的内存或者驱动也会导致SegFault
debug Segmentation Fault错误的建议
要调试Segmentation Fault可以尝试如下技术:
- 使用gdb来跟踪问题的准确来源
- 确保正确的硬件安装和配置
- 已经安装了所有补丁以及更新好系统
- 确保在jail内部已经安装了所有依赖
- 对于支持core dump的程序,如Apache已经开启Apache core dump配置
- 使用strace来诊断
- 使用Google查找解决方法
- 修复C程序中的逻辑错误,例如指针,空指针,数组等等
- 使用gdb来分析core dump文件
这里有一个获取MySQL core文件的案例
延伸阅读
PHP-FPM: SegFault every few seconds 提供了有关SegFault的一些很好的文档介绍:
- PHP-FPM - WARNING: failed processes threshold (10 in 60 sec) is reached, initiating reload Errors
- Why Does The Segmentation Fault Occur on Linux / UNIX Systems?
- strace知识:
- gdb
With gdb backtrace and PHP debug compiled mode where centmin.sh has a PHPDEBUGMODE variable which you can set to PHPDEBUGMODE=y and recompile php via centmin.sh menu option 5 to enable debug mode for PHP-FPM. After troubleshooting set PHPDEBUGMODE=n and recompile php via centmin.sh menu option 5 again to disable debug mode.
PHPDEBUGMODE=n # --enable-debug PHP compile flag