天天看點

如何找出發生SEGV記憶體錯誤的程式

​問題

​18-feb-2014 15:48:45] warning: [pool www] child 11274 exited on signal 11 (sigsegv) after 0.089068 seconds from start

顯然11274程序運作過程中遇到了段錯誤導緻程序異常退出了。繼續追查發現是php的hsf擴充在啟動初始化的時候遇到記憶體問題導緻段錯誤。

滄老師這個段錯誤程序你怎麼定位到是hsf擴充的問題?

分析過程

​發現段錯誤:

日志中的資訊表明,程序号為11274的程序由于收到sigsegv信号而退出了。收到這個信号的時候,程式是可以生成core檔案的。不過通過日志我們可以知道程序11274退出時沒有生成core檔案。因為在php-fpm的日志中,如果退出時生成了core檔案,日志中會有“sigsegv - core dumped”字樣。如:

​[20-feb-2014 08:37:59] warning: [pool www] child 15845 exited on signal 11 (sigsegv - core dumped) after 1.051001 seconds from start

​生成core檔案:

為啥沒生成core檔案?是因為我們的系統做了限制。執行如下指令可以檢視限制情況:

如何找出發生SEGV記憶體錯誤的程式

<img src="http://www.bo56.com/wp-content/uploads/2014/03/ulimit.jpg" alt="ulimit" width="424" height="300" class="alignnone size-full wp-image-338" /></a><br /> 可以看出,系統對于core檔案大小預設限制是0.也就是說不能生成core檔案。可以通過以下指令設定大小。

$ulimit -c unlimited

通過指令,我們就把系統對于core檔案的大小限制去除了。

如何找出發生SEGV記憶體錯誤的程式

<img src="http://www.bo56.com/wp-content/uploads/2014/03/ulimit1.jpg" alt="ulimit1" width="400" height="215" class="alignnone size-full wp-image-339" /></a><br /> 設定完後,重新開機了php-fpm 程序。剩下的事情,就是坐等core檔案生成了。

​第二天,檢視php-fpm日志,發現了如下記錄:

[20-feb-2014 08:37:59] warning: [pool www] child 15845 exited on signal 11 (sigsegv - core dumped) after 1.051001 seconds from start

[20-feb-2014 08:39:04] warning: [pool www] child 17803 exited on signal 11 (sigsegv - core dumped) after 0.927973 seconds from start

[20-feb-2014 08:42:18] warning: [pool www] child 23491 exited on signal 11 (sigsegv - core dumped) after 0.798308 seconds from start

說明,core檔案已經生成。

gdb分析core檔案:

既然core檔案生成了,現在該gdb上場了。通過如下指令檢視程式退出時的棧資訊。

再繼續分析其他的兩個core檔案,發現也都有這個棧資訊。基本可以肯定是hsf的問題了。

另外,在/var/log/message 中也發現了如下記錄:

mar 13 14:40:07 s006132.cm6 kernel: : [5332900.567547] php-fpm[31017]: segfault at 30 ip 00007fdc74df3310 sp 00000000435b8040 error 4 in libeasy.so.0[7fdc74de3000+23000]

libeasy.so 正是hsf中調用的。進一步确認是執行hsf程式時出現問題的。