最近在 linux qt上做開發,發現程式異常crash,用core dump檔案也沒有記錄下來有用的資訊,如下圖:
定位程式異常crash 的過程百般痛苦,雖然最後是用 把core dump檔案大小的限制取消,完整記錄程式崩潰的堆疊資訊結合gdb 定位到問題,但發現網友分享的 不用core -dump 定位bug的方法,故記錄下來,以備他日試用。
有時寫c/c++程式,執行後出現core, 如果有core檔案則可以gdb方便的定位問題,
可是,當core檔案找不到(或被刪除)時如何定位?
剛做了個測試,在沒有core檔案的情況下對程式bug進行定位
cat core.cpp
1 #include
2 3 int main(int argc, char** argv)
9 10 return 0;
11 }
g++ -g core.cpp -o core
./core
segmentation fault
/var/log]# vim messages
nov 24 04:02:08 i237 syslogd 1.4.1: restart.
nov 25 13:55:01 i237 kernel: testreg[19978]: segfault at 000000000000000a rip 00000036ed078d50 rsp 00007fffa7125888 error 4
nov 25 13:58:20 i237 kernel: testreg[20711]: segfault at 00000000000003e8 rip 00000036ed078d70 rsp 00007fff8e28ac98 error 4
nov 25 16:19:10 i237 kernel: core[17962]: segfault at 0000000000000000 rip 0000000000400677 rsp 00007fff0c53dc30 error 6
最後乙個core[17962]即是剛才生成core的程序
可以到這個core.cpp生成core的目錄下
執行:
addr2line 0000000000400677 -e /path/./core
輸出:....../core.cpp:7
這樣我們可以初步定位到位core.cpp第7行的問題,回到程式中看是非法位址的賦值
我們看下man addr2line
name
addr2line - convert addresses into file names and line numbers.
這個命令本身就是把位址轉成名稱和行號的,只是我們對於這個位址需要在message日誌中看rip位址才能得到
另外,error 後的數字轉換到二進位制依次對應描述如下:
bit2: 值為1表示是使用者態程式記憶體訪問越界,值為0表示是核心態程式記憶體訪問越界
bit1: 值為1表示是寫操作導致記憶體訪問越界,值為0表示是讀操作導致記憶體訪問越界
bit0: 值為1表示沒有足夠的許可權訪問非法位址的內容,值為0表示訪問的非法位址根本沒有對應的頁面,也就是無效位址
所以從這個error 6也可以知道原因是 使用者程式操作訪問越界
最後百科裡借用乙個暫存器:
專用暫存器
專用暫存器包括: rip、rsp和rflags以及段暫存器cs、ds、es、ss、fs和gs。
rip(指令指標)rip定址**段儲存區內的下一條指令。當微處理器工作在實模式下時,這個暫存器是ip(16位);當80386及更高型號的微處理器工作於保護模式下時,則是eip(32位)。注意,8086、8088和80286不包含eip暫存器,而且只有80286及更高型號的微處理器可以工作於保護模式。指令指標指向程式的下一條指令,用於微處理器在程式中順序地定址**段內的下一條指令。指令指標也可由轉移指令或呼叫指令修改。在64位模式中,rip包含40位位址匯流排,可用於定址1tb平展模式位址空間。
rsp(堆疊指標)rsp定址乙個稱為堆疊的儲存區。通過這個指標訪問堆疊儲存器資料,具體操作將在本書後面講解訪問堆疊儲存器資料的指令時再進行說明。這個暫存器作為16位暫存器被引用時,為sp;如果作為32位暫存器,則是esp。
linux 下如何開啟core dump檔案開關
在linux下面就簡單的許多。只要開啟相應的開關,linux會自動在程式crash時生成相應的core檔案。這個檔案和window下的dump檔案類似。下面是簡單的一些步驟 1.檢視當前是否已經開啟了此開關 通過命令 ulimit c 如果輸出為 0 則代表沒有開啟。如果為unlimited則已經開...
linux 下如何開啟core dump檔案開關
在linux下面就簡單的許多。只要開啟相應的開關,linux會自動在程式crash時生成相應的core檔案。這個檔案和window下的dump檔案類似。下面是簡單的一些步驟 1.檢視當前是否已經開啟了此開關 通過命令 ulimit c 如果輸出為 0,則代表沒有開啟。如果為unlimited則已經開...
Linux下如何除錯coredump檔案
1 設定系統相關引數,否則不會產生coredump檔案。echo ulimit c 1024 etc profile設定完後,重新登入系統或者source etc profile,使生效。2 編寫測試檔案,dump.cpp。include include void crash int main 3 ...