本篇紀錄如何從程式的 segmentation fault,配合 dmesg 和 addr2line 來除錯,
查出程式是掛(死)在哪個原始碼的第幾行。
首先先來寫一個會讓程式崩潰的程式,
再來配合使用 dmesg 查 kernel log 看是掛在哪個記憶體位置,
再來配合使用 addr2line 查出該記憶體位置是在程式碼的那一行
開始吧!
寫一個會讓程式崩潰的程式
讓一個 ptr 指標指向 NULL, 使用 printf 印出 ptr 指向的值,
使用 g++ cpp-crash.cpp -o a.out
進行編譯,
之後再執行 a.out
就會發現程式執行到一半發生segmentation fault (core dumped) 了!1
2
3
4
5
6
7
8
9
10
11
12// g++ cpp-crash.cpp -o a.out
void myprint(int* ptr) {
printf("%d\n", *ptr);
}
int main() {
int *ptr = NULL;
myprint(ptr);
return 0;
}
輸出1
Segmentation fault (core dumped)
使用 dmesg 查 kernel log 看是掛在哪個記憶體位置
接著 dmesg 指令可以查看發生段錯誤的程式名稱、造成錯誤發生的記憶體地址、指令指標地址、堆疊指標地址、錯誤程式碼、錯誤原因等,
接著使用 dmesg 看看記憶體位置,找到顯示的 ip 為 00000000004005361
a.out[14306]: segfault at 0 ip 0000000000400536 sp 00007ffce9c58050 error 4 in a.out[400000+1000]
也可用 Android logcat 上 backtrace 的 pc 記憶體位置來去查。
配合使用 addr2line 查出該記憶體位置是在程式碼的那一行
最後使用 addr2line 找出 ip 0000000000400536 在程式碼第幾行1
$ addr2line -Cfie ./a.out 0000000000400536
輸出結果如下1
2myprint(int*)
??:?
上列資訊顯示程式死在 myprint 這個函式裡,但是看不到行數,
原因是因為使用 g++ 時沒用 -g
參數讓它編譯出有除錯的資訊
使用 g++ cpp-crash.cpp -o a.out -g
再編譯一次吧!
之後在執行一次,將 ip 拿去用 addr2line 查出的結果如下,1
2myprint(int*)
/home/xxx/cpp-crash.cpp:5
這次就可以很清楚看到原始檔名稱與行數了!
這樣就可以回去程式碼裡好好看看是哪裡寫錯了。
使用 nm 查詢
使用 nm 指令 nm -gC a.out
可以導出 symbol,
如下所示,發現 myprint 的位置是 0000000000400526 跟上面的 ip 很接近
1 | 0000000000601038 B __bss_start |
參考
[1] 使用dmesg和addr2line查找程序崩潰後的現場報告 | cpper
http://www.cpper.cn/2016/09/09/develop/dmesg-addr2line/
[2] gdb調試core dump入門實踐(順便複習一下之前介紹過的addr2line命令調試) - stpeace的專欄
https://blog.csdn.net/stpeace/article/details/49806473
[3] 關於Segmentation fault (core dumped)幾個簡單問題的整理
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/560380/
什麼是Core Dump,可以看看這篇的介紹
[4]【已解決】Linux下出現Segmentation Fault(core dump)錯誤 - YSBJ123的博客
https://blog.csdn.net/YSBJ123/article/details/50035169
其他也不錯的文章,這篇有好幾種讓你產生 Segmentation Fault 的程式
從 https://www.cnblogs.com/panfeng412/archive/2011/11/06/segmentation-fault-in-linux.html 轉載
[5] 内核 segfault 报错分析 - Jamin Zhang
https://jaminzhang.github.io/linux/Kernel-Segfault-Analysis/
解釋 error 4 代表什麼意思
其它相關文章推薦
addr2line 用法
nm 用法與範例