本篇文章記錄在coredump除錯過程中記錄的其它事項。
一般地,除錯的方式多種多樣,不可能將其一網打盡。就筆者而言,一般喜歡用print**,分段註解法,版本回退法,等等。實在無招,則用coredump檔案除錯了。在筆者「眾多」經驗中,程式掛掉原因多種多樣,像記憶體洩漏造成無記憶體可用,檔案/socket開啟未關閉被耗盡。所以程式設計的規範還是很關鍵的,這不單單是說編碼命名風格,還有整體程式設計的設計和細心程度,比如指標的判斷,陣列範圍不要越界,自己申請的記憶體要記得釋放,等等。
在嵌入式上進行除錯的方法很多,網上很多文章介紹了gdbserver的方式,同時結合codeblock則可以達到ide除錯目的。但可惜往往是些簡單例子。實際中,嵌入式裝置執行的程式,可能和驅動模組實時互動,還和網路密切頻繁通訊,另外還開了n個執行緒,m個程序,在如此龐大的系統中,一旦出現段錯誤,除了靠列印資訊外,還可以靠開發人員自身的經驗,靠對系統的熟悉程度進行排查。而coredump作為事後分析手段,也大量被應用在日常工作中。
但是,嵌入式的除錯還是比較困難的。因為,要麼裝置所用的系統是唯讀的,要麼儲存介質的容量很小,當大型系統崩潰時,產生的coredump檔案體積很大,無法在儲存介質上儲存,則會丟失很多資訊,無法用gdb除錯。
另外乙個因素是看門狗。很多系統都有看門狗機制,一旦程式崩潰則會即刻復位,無法拿到coredump進行分析。
下面說說筆者的經驗:
1、設定ulimit,可以在程式**中設定,也可以在啟動指令碼中設定,只要保證在程式執行環境中設定就行了。比如,你是telnet到系統中手動執行程式的話,一定要telnet終端中設定ulimit後再執行程式。
2、將看門狗禁止掉或延長時間。有的裝置可以短接主機板的排針禁止狗,有的則可以通過**禁止狗。比如我移植的系統,直接用echo就可以把狗禁止掉。
3、使用nfs掛載,以便儲存生成的coredump檔案。
4、編譯器和偵錯程式版本一定要對應起來。否則會出現很多莫名其妙的問題,如下文將講述到的問題。
1、使用-o2優化,或者strip過後的二進位制程式,是無法產生除錯資訊的,此時用gdb檢視不到函式名稱。所以要用-g編譯選項,使其產生除錯資訊,同時不要將程式strip。
2、庫版本不對。可能是真的庫版本不正確,也可能是路徑不正確。遇到庫不對應的問題,可以先開啟gdb,使用set solib-absolute-prefix 和set solib-search-path來設定庫路徑。示例如下(按實際路徑填寫):
#gdb
#set solib-absolute-prefix "/home/latelee/cross/arm-linux/lib"
#set solib-search-path "/home/latelee/cross/arm-linux/lib"
#file a.out
#core-file core
網上有文章對此做了介紹:《gdb除錯coredump檔案,函式名稱是問號》,本文就不展開討論了。
1、一般在函式內申請記憶體的,要在本函式內釋放掉,如果申請空間少,建議直接用陣列,以免忘記申請造成記憶體洩漏。如果實在要使用二級指標來儲存函式內申請的空間,則要在函式宣告處註明其用法。
2、任何時候,一定要判斷指標的有效性。另外要特別注意多級指標情況。比如onvif獲取編碼引數時,有一項是獲取ip位址的**片段示例:resp.configuration->multicast->address->ipv4address。這個示例中,一定要逐級判斷指標是否合法。
3、使用printf、scanf等函式時,要注意引數一致性。預設的c庫在gcc中是有檢查的,注意編譯警告可減小其段錯誤概率。但如果是自己寫的列印log函式,未盡能檢查。筆者的這篇文章可參考:《乙個可變引數型別檢查的示例》
4、開啟的資源要及時釋放,特別是return、break、goto這些地方,很容易忘記關閉。資源包括但不限於:socket、普通檔案控制代碼(檔案描述符)、目錄,等等。筆者的這篇文章可參考:《遇到乙個因socket未關閉引發的檔案控制代碼用完問題》
5、建議使用cppcheck進行一次**檢查。筆者的這篇文章可參考:《使用cppcheck檢測**警告、錯誤》
李遲 2016.5.31 周二 夜
linux下core dump的妙用
在unix系統中,常將 主記憶體 main memory 稱為核心 core 因為在使用半導體作為記憶體材料之前,便是使用核心 core 而核心映像 core image 就是 程序 process 執行當時的記憶體內容。當程序發生段錯誤或收到 訊號 signal 而終止執行時,系統會將核心映像寫入...
Linux下core dump (段錯誤)
在linux下開發時,如果程式突然崩潰了,也沒有任何日誌。這時可以檢視core檔案。從core檔案中分析原因,通過gdb看出程式掛在 分析前後的變數,找出問題的原因。當程式執行的過程中異常終止或崩潰,作業系統會將程式當時的記憶體狀態記錄下來,儲存在乙個檔案中,這種行為就叫做core dump 中文有...
linux 下如何開啟core dump檔案開關
在linux下面就簡單的許多。只要開啟相應的開關,linux會自動在程式crash時生成相應的core檔案。這個檔案和window下的dump檔案類似。下面是簡單的一些步驟 1.檢視當前是否已經開啟了此開關 通過命令 ulimit c 如果輸出為 0 則代表沒有開啟。如果為unlimited則已經開...