高階gdb之core dump的除錯

2022-09-10 21:45:29 字數 3413 閱讀 4839

basic perl等語言處理的可以說是user的資料, c可以說在那邊把資料在記憶體移來移去, 組語可說把資料在暫存器搬來搬去, 越低階的處理表示握有的資源越少

所以c處理不好的話很容易記憶體跨出範圍, 或者系統毀了(panic), 這時都會產生乙個core dump, 就是毀掉的瞬間記憶體內部的內容會搬到乙個檔案core, core file 包含了程式的read/write的memory部份, 也就是程式躺在記憶體時的狀態, executable只是乙個可執行檔也就是程式躺在硬碟時。 gdb可以根據這個檔來除錯,只是這時的target是core 或exec 不是remote。 通常這可以拿來做系統毀掉時的debug

gdb a.out core        命令列上給executable與core file

target exec a.out 跟file命令不一樣的是exec不load symbol table

只loadtext與initialized data這時程式只可run

無法看source code與檢查任何變數

target core core core file

用下面程式做例子

#include int main()

跑它之後產生core dump檔並用gdb來看它

[cyril@megami cyril]gdb a.out core

gnu gdb 5.0

gdb is free software, covered by the gnu general public license, and you are

welcome to change it and/or distribute copies of it under certain conditions.

type "show copying" to see the conditions.

there is absolutely no warranty for gdb. type "show warranty" for details.

this gdb was configured as "sparc-sun-solaris2.7"...

core was generated by `./a.out'.

program terminated with signal 11, segmentation fault.

reading symbols from /usr/lib/libc.so.1...done.

loaded symbols for /usr/lib/libc.so.1

reading symbols from /usr/lib/libdl.so.1...done.

loaded symbols for /usr/lib/libdl.so.1

reading symbols from /usr/platform/sunw,ultra-enterprise/lib/libc_psr.so.1...

done.

loaded symbols for /usr/platform/sunw,ultra-enterprise/lib/libc_psr.so.1

#0 0x10870 in main () at core.c:5

5 *x = 1;

(gdb) print x

$1 = 0x0

(gdb) print *x

cannot access memory at address 0x0

當然這例子很簡單,不過不用自己一步步追到死掉的地方, gdb a.out core自動用file命令load了symbol table進來,所以我可以用 print x來看它。通常捉到問題點就是用bt(backtrace)捉出之前到底叫了甚麼。

這篇是 "learning core dump from the hard way", 寫下幾個注意事項, 後來才發現 man core 就可以看到全部東西:

測試若執行的程式有讀 terminal input, 可直接輸入 ctrl + \ 送出 sigquit。或用指令 kill -quit pid 或 kill -abrt pid, 要求程式產生 core dump, 藉此測試目前的設定是否 ok。

參考《從 /proc/pid/status 了解執行中程式處理 signal 的方式》, 先確認 signal handler 沒有被覆蓋掉, 才可放心測試。

ulimit / setrlimit(rlimit_core, ...)

ubuntu 預設為 ulimit -c 0, 表示不產生 core dump, 所以要先執行 ulimit -c unlimited 允許產生 core dump。可以將這行寫到 ~/.bashrc 裡, 以後就缺省會產生 core dump。或在程式裡呼叫 setrlimit(rlimit_core, &limit) 也可以。

/proc/sys/kernel/core_pattern

預設 core dump 的檔名可能不合使用, 參考《setting the core dump name schema》, 可用

$ echo 

"core.%e.%p.%t"

|sudo tee

/proc

/sys

/kernel

/core_pattern

改變 core dump 的檔名, 這樣檔名會記錄是程式名稱、pid、發生的時間。在 multi-process 或 multi-thread 時特別有用。若希望每次開機都會生效, 則要在 /etc/sysctl.conf 加入 kernel.core_pattern = core.%e.%p.%t。

core pattern 可以是 "|program", 這樣會將 core dump 導到 program 的標準輸入, 可以自己寫 program 做控制。像是 core dump 太頻繁時, 取樣留下幾個就好, 以免一下就塞爆硬碟。同樣的, %e 那些引數也可以接在 program 後當引數用, 像是 "|program core.%e.%p.%t", 自己的 program 就能從 ar**[1] 裡取得適合的檔名。需要特別注意的是, | 和 program 之間不可以有空白。

setuid / setgid

若確認 ulimit -c 有設好, core_pattern 沒寫到奇怪的地方 (像是 /dev/null), 硬碟也仍有空間, 卻仍無法產生 core dump, 可能是用到 setuid。用 ls -l 檢查一下, 或用 strace -esetuid 檢查。linux 為了安全考量, 在使用 setuid/setgid 後, 會自動禁用 core dump。

若確實有觸發 setuid 的話, 在 setuid 後執行:

prctl

(pr_set_dumpable,1

);

重新允許產生 core dump, 應該就 ok 了。

2013-03-26 更新

GDB之coredump的學習

在linux環境下執行程式的時候有的時候會出現一些問題,這個時候就可以使用gdb工具進行除錯,以下是公司實習期間學習gdb的一些總結。1 gdb的簡介 gdb是gnu開源組織發布的乙個強大的unix下的程式除錯工具。一般來說,gdb主要完成以下四個方面的功能 1 啟動你的程式,可以按照你的自定義的要...

GDB除錯coredump檔案

linux上程式崩潰起來挺煩人,不過linux 比較好的是有gdb.echo ulimit c unlimited etc profile 然後記得敲入命令 source etc profile然後敲入命令 ulimit c效果如下 確認能否生成coredump檔案,使用如下命令 使用時注意,我在測...

gdb除錯coredump檔案

linux上程式崩潰起來挺煩人,不過linux 比較好的是有gdb.echo ulimit c unlimited etc profile 然後記得敲入命令 source etc profile然後敲入命令 ulimit c效果如下 確認能否生成coredump檔案,使用如下命令 使用時注意,我在測...