Linux下的core dump(二)

        之前一篇文章主要介紹了core dump的一些基本概念以及產生的基本原因,這篇文章主要聊一下程序出core之後如何進行最基本的定位。

一、簡單的直觀定位

        有時候不用去具體分析core文件我們就能初步定位到代碼問題。例如:在程序執行到每次某一功能時,就會現core dump。例如程序每次點擊跳轉頁面、或者重新設置參數時。(根據具體出現問題時的操作,去定位程序相應的代碼模塊)


二、 使用日誌或者printf輸出信息定位

這種方式在代碼開發期間自己調試經常會使用,省事且高效。

在程序的重要代碼附近加上像printf這類輸出信息,這樣可以跟蹤並打印出段錯誤在代碼中可能出現的位置。可以使用條件編譯指令#ifdef DEBUG和#endif把printf函數包起來。這樣在程序編譯時,如果加上-DDEBUG參數就能查看調試信息;否則不加該參數就不會顯示調試信息。


三、 使用core文件和gdb進行定位 (命令:gdb [exec file] [core file])

1、情形1問題每次必現,或者復現比率非常高的case且堆棧信息未被破壞。看如下簡單例子:

             a.編譯運行如下代碼:


編譯是能正常通過的,但在執行時出core:


      

              b.使用gdb ./a.out core.a.out.22797 進行調試。使用bt查看堆棧信息,使用frame n調用具體的堆棧信息


       

        最後定位到出core代碼位置在第9行,變量未分配空間。




2、情形2:問題不好復現!而且出現無符號和棧破壞情況下。

      bt查看到堆棧信息被破壞。


這種情況下,查看寄存器信息: rbp的值很奇怪,基本確定棧被破壞了(bt不正常,也應該看一下棧是否出問題了)。


RBP出現了問題,我們就可以通過RSP來手動獲取調用堆棧。因爲RSP是不會被破壞的,如下圖看到了特殊的字符!,1234567890,推測可能是字符串"Hello,World!,1234567890“這個字符串溢出導致棧被破壞。

(rsp是棧指針寄存器64位,指向棧頂。相當於32位彙編裏的esp16位的sp)



四、使用輔助工具(valgrind )

Valgrind是一款用於內存調試、內存泄漏檢測以及性能分析的軟件開發工具在它的環境中運行你的程序來監視內存的使用情況。比如語言中的mallocfree或者C++中的new delete。使用Valgrind的工具包,你可以自動的檢測許多內存管理和線程的bug,避免花費太多的時間在bug尋找上,使得你的程序更加穩固。


五、小結


     二分調試就是通過某種特徵(比如程序崩潰、某個變量的值/內存中的數據、是否出現某條日誌、是否出現某個現象,以及任何有用的特徵),加上一個能把問題可能出現的空間劃分兩半的一個點(一行assert、一個斷點、一行打日誌的代碼、一個版本號、等等),二者結合就能把問題可能出現的範圍縮小(比如能判斷出錯誤代碼出現在那行assert之前等之類),跟二分搜索一樣。


           Backtrace函數對長時間運行程序的分析,在程序出錯時打印出函數的調用堆棧是非常有用的.



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