天天看點

linux 下 core 相關知識總結

在以往的測試過程中,每當遇到程式出現 coredump 的狀況,我的第一反應就是有 bug,讓開發定位原因,但是如果自己能夠去挖掘原因,在與開發溝通的過程中能明确指出問題所在,一定能提高溝通,定位問題的效率。

最近利用空餘時間學習了一下 core 的基本知識,發現有很多新的發現(其實是自己以前不知道,呵呵),在這裡分享給大家,希望對大家有所幫助。

在一個程式崩潰時,它一般會在指定目錄下生成一個 core 檔案,core 檔案包含了程式運作時的記憶體,寄存器狀态,堆棧指針,記憶體管理資訊等,可以幫助我們進行調試。

記憶體通路越界

多線程程式使用了線程不安全的函數

多線程讀寫的資料未加鎖保護

非法指針

堆棧溢出

使用 ulimit –c 指令可檢視 core 檔案的生成開關,若結果為0,則表示關閉了此功能,不會生成 core 檔案。

使用 ulimit –c filesize 指令,可以限制 core 檔案的大小,如果此檔案大小超過限制,将會被裁剪,最終生成不完整的 core 檔案。若為 ulimit –c unlimited ,則不限制 core 檔案的大小。

注意:在測試前需檢查 core 檔案的開關是否打開;在測試過程中發現程式異常退出,但沒有産生 core ,我們也需要第一時間檢查 core 檔案是否打開;有幾種方式讓程式産生 core 。

修改 core 檔案生成大小的配置,例如 ulimit –c 1000,這個修改隻對目前會話有效。

通過将一個相應的 ulimit 語句添加到由登入 shell 讀取的檔案,如 ~/.profile ,例如在wx使用者下的 ~/.profile 增加 ulimit –c unlimited ,那麼對于 wx 使用者就可以生成沒有大小限制的 core 檔案,但是對于其他使用者不生效。

修改 /etc/profile 檔案,将預設配置 # ulimit -Sc 0 ,将配置改成可用,并設定為 ulimit -Sc unlimited ,那麼該機器的所有使用者都将生成無大小限制的 core 檔案。

在程式的啟動腳本(例如 restart.sh )的開頭設定 ulimit –c unlimited ,這隻是對該程序有用。

若系統生成的 core 檔案不帶其他任何擴充名稱,則全部命名為 core,新的 core 檔案生成将會覆寫原來的 core 檔案。

<code>/proc/sys/kernel/ core_uses_pid</code> 可以控制 core 檔案的檔案名是否添加 pid 作為擴充。檔案内容為1表示添加 pid ,生成的 core 檔案格式為 <code>core.XXXX</code> ,為0表示不添加。可以通過以下指令修改此檔案: <code>echo “1”&gt; /proc/sys/kernel/ coreuses_pid</code> 。

<code>/proc/sys/kernel/ core_pattern</code>可以控制 core 檔案儲存位置和檔案名格式。可以通過以下指令修改此檔案:

<code>echo “/corefile/core-%e-%p-%t”&gt; core_pattern</code>,可以将 core 檔案統一生成到 / corefile 目錄下,産生的檔案名為 core - 指令名 - pid - 時間戳,以下是參數清單:

如果我們不清楚 core 是由哪個程序産生的,我們可以通過使用指令 “ file core 檔案 ”來檢視。

例如 core 檔案是由 test 這個程序産生的,那麼通過指令 “ gdb test corefile ” 檢視 core 檔案的内容,在輸入 bt 或 where 檢查程式運作到哪裡,來定位 coredump 的行。

我們檢視一個core的例子,例如getd在啟動時出現了 core,内容為:

linux 下 core 相關知識總結

我們可以看到在 getdapp.cpp 的1108行調用 assert 函數出現錯誤,進而抛出了信号,産生了 core 。

core 顯示的内容為堆棧資訊,我們可以通過輸入 up 來檢視上一層堆棧的資訊,例如:我們最初看到 core 檔案資訊為:

linux 下 core 相關知識總結

連續輸入 up 後,顯示内容為:

linux 下 core 相關知識總結

有些 core 能簡單的定位出,但是有些 core 檔案的定位還需要了解 gdb 常用的指令,通過這些指令與 core 檔案結合,我們才能快速定位出問題。下面簡單的介紹一下 gbd 常用的指令: