Linux下的段錯誤(Segmentation fault)產生的原因及除錯方法
段錯誤就是訪問了錯誤的記憶體段,一般是你沒有許可權,或者根本就不存在對應的實體記憶體,尤其常見的是訪問0地址. 前32位是儲存由它指 向的gdt表, 後13位儲存相應於gdt下標, 最後3位包括了程式是否在記憶體中以及程式的在cpu中的執行級別. 指向的gdt是由以64位為一個單位的 表,在這張表中就儲存著程式執行的程式碼段以及資料段的起始地址以及與此相應的段限和頁面交換
解決方法
|
作為一個熟練的C/C++程式設計師,以上程式碼的bug應該是很清楚的,因為它嘗試操作地址為0的記憶體區域,而這個記憶體區域通常是不可訪問的禁區,當然就會出錯了。我們嘗試編譯執行它: |
果然不出所料,它出錯並退出了。 |
哦?!好像不用一步步除錯我們就找到了出錯位置d.c檔案的第4行,其實就是如此的簡單。 |
以 上資料摘自man page(man 5 core)。不過奇怪了,我的系統上並沒有找到core檔案。後來,憶起為了漸少系統上的拉圾檔案的數量(本人有些潔癖,這也是我喜歡Gentoo的原因 之一),禁止了core檔案的生成,查看了以下果真如此,將系統的core檔案的大小限制在512K大小,再試: |
core檔案終於產生了,用gdb除錯一下看看吧: |
哇,好歷害,還是一步就定位到了錯誤所在地,佩服一下Linux/Unix系統的此類設計。 |
編譯執行效果如下: |
怎麼樣?是不是依舊很酷? |
編譯執行結果如下: |
這次你可能有些失望,似乎沒能給出足夠的資訊來標示錯誤,不急,先看看能分析出來什麼吧,用objdump反彙編程式,找到地址0x804876f對應的程式碼位置: |
|