为什么会发生segfault

什么情况下会出现段错误(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的一些很好的文档介绍:

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

参考

Last updated