segfault at error 0~7

 [root@168 logs]# tail /var/log/messages

Oct   9 00:29:20 168 kernel: httpd[24110]: segfault at 00007fff5989d878 rip 00002b8dd9595174 rsp 00007fff5989d880 error 6
Oct   9 00:34:55 168 kernel: httpd[24323]: segfault at 00007fff5989d878 rip 00002b8dd9595174 rsp 00007fff5989d880 error 6
Oct   9 00:47:26 168 kernel: httpd[24997]: segfault at 00007fff5989d878 rip 00002b8dd9595174 rsp 00007fff5989d880 error 6

答:

   這種信息一般都是由內存訪問越界造成的,不管是用戶態程序還是內核態程序訪問越界都會出core, 並在系統日誌裏面輸出一條這樣的信息。這條信息的前面分別是訪問越界的程序名,進程ID號,訪問越界的地址以及當時進程堆棧地址等信息,比較有用的信息是 最後的error number. 
在上面的例子中,error number是6, 轉成二進制就是110, 即bit2=1, bit1=1, bit0=0, 按照上面的解釋,我們可以得出這條信息是由於用戶態程序讀操作訪問越界造成的。
error number是由三個字位組成的,從高到底分別爲bit2 bit1和bit0,所以它的取值範圍是0~7.
bit2: 值爲1表示是用戶態程序內存訪問越界,值爲0表示是內核態程序內存訪問越界
bit1: 值爲1表示是寫操作導致內存訪問越界,值爲0表示是讀操作導致內存訪問越界
bit0: 值爲1表示沒有足夠的權限訪問非法地址的內容,值爲0表示訪問的非法地址根本沒有對應的頁面,也就是無效地址 
根據segfault信息調試定位程序bug:
#include<stdio.h>int main(){        int *p;        *p=12;        return 1;}
1. gcc testseg.c -o testseg -g,運行./testseg查看dmesg信息如下:
testseg[26063]: segfault at 0000000000000000 rip 0000000000400470 rsp 0000007fbffff8a0 error 6
2. 運行addr2line -e testseg 0000000000400470,輸出如下:
/home/xxx/xxx/c/testseg.c:5 [...]

***********************

內存不足不會引起段錯誤。段錯誤通常出現在訪問了非法的地址後,非法地址分爲3類:
1. 訪問的地址沒有對應的物理內存。這類錯誤主要出現在越界訪問,例如棧越界。比如說當前進程的棧只有5個頁和它對應,共20k大小(x86平臺),你訪問的地址超過了這個範圍,就會發生segmentation fault。

2.對地址的操作與該地址的屬性不符合。例如該地址對應的內存是隻讀的,如文本段,你卻試圖進行寫操作。

3.低權限訪問高權限地址。這類情況發生在用戶進程試圖訪問內核空間。例如x86中,TASK_SIZE以上的地址爲內核空間,當用戶態進程試圖訪問這些地址時,segmentation fault。********************

 

estseg[24850]: segfault at 0000000000000000 rip 0000000000400470 rsp 0000007fbffff8a0 error 6
這種信息一般都是由內存訪問越界造成的,不管是用戶態程序還是內核態程序訪問越界都會出core, 並在系統日誌裏面輸出一條這樣的信息。這條信息的前面分別是訪問越界的程序名,進程ID號,訪問越界的地址以及當時進程堆棧地址等信息,比較有用的信息是最後的error number. 在上面的信息中,error number是4 ,下面詳細介紹一下error number的信息:
在上面的例子中,error number是6, 轉成二進制就是110, 即bit2=1, bit1=1, bit0=0, 按照上面的解釋,我們可以得出這條信息是由於用戶態程序讀操作訪問越界造成的。

error number是由三個字位組成的,從高到底分別爲bit2 bit1和bit0,所以它的取值範圍是0~7.
bit2: 值爲1表示是用戶態程序內存訪問越界,值爲0表示是內核態程序內存訪問越界 
bit1: 值爲1表示是寫操作導致內存訪問越界,值爲0表示是讀操作導致內存訪問越界 
bit0: 值爲1表示沒有足夠的權限訪問非法地址的內容,值爲0表示訪問的非法地址根本沒有對應的頁面,也就是無效地址 
根據segfault信息調試定位程序bug:
#include
int main()
{
int *p;
*p=12;
return 1;
}

1. gcc testseg.c -o testseg -g,運行./testseg查看dmesg信息如下: 
testseg[26063]: segfault at 0000000000000000 rip 0000000000400470 rsp 0000007fbffff8a0 error 6 
2. 運行addr2line -e testseg 0000000000400470,輸出如下: 
/home/xxx/xxx/c/testseg.c:5

 

參考資料:

http://en.wikipedia.org/wiki/Segmentation_fault

http://hi.baidu.com/sky_hacker/blog/item/86a933dcd6a858abcc116623.html

http://blog.5iwww.com/read.php/1109.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章