linux core檔案除錯

2021-06-27 12:15:20 字數 4642 閱讀 1107

在完成公司專案,測試程序的時候,經常會發現日誌到了某一段特定的**的時候就沒了,程序直接退出,也沒有捕獲到任何的異常資訊,如果日誌列印的較多還可能比較容易發現問題,如果日誌較少,就很難進行進一步的查錯了。

但是發現在該目錄下生成了乙個core檔案,可以幫助我們查詢程式崩潰的原因。

在linux系統下,如果程序不能正常執行,就可能會產生core檔案。core檔案就是當前記憶體狀態的乙個映像,同時加上一些除錯資訊。

bug和作業系統或硬體的保護機制都會導致程式異常終止,作業系統會kill掉這些程序並產生core檔案。

使用 ulimit -a 命令可以檢視當前系統資源的一些限制資訊,如下圖所示:

其中的core file size 如果設定為0的話,當程式崩潰的時候就不會產生core檔案。

#設定core檔案大小為無限

ulimit -c unlimited

#阻止系統生成core檔案

ulimit -c 0

注意:這條命令只在當前生效,如果希望永久生效,就需要在.bash_profile中加上這條命令。

/proc/sys/kernel/core_uses_pid可以控制產生的core檔案的檔名中是否新增pid作為擴充套件,如果新增則檔案內容為1,否則為0。需要有超級使用者的許可權才能進行修改。

/proc/sys/kernel/core_pattern 可以設定格式化的 core檔案儲存位置或檔名,預設的是|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e。需要修改的話,可以使用如下命令:

echo "/corefile/core-%e-%p-%t"> /proc/sys/kernel/core_pattern

將會控制所產生的core檔案會存放到/corefile目錄下,產生的檔名為core-命令名-pid-時間戳

以下是引數列表:

%p - insert pid into filename 新增pid

%u - insert current uid into filename 新增當前uid

%g - insert current gid into filename 新增當前gid

%s - insert signal that caused the coredump into the filename 新增導致產生core的訊號

%t - insert unix time that the coredump occurred into filename 新增core檔案生成時的unix時間

%e - insertcoredumping executable name into filename 新增命令名

在linux上可以使用gdb來除錯core檔案,格式為:

gdb [程式名] [core檔名]

如果你不知道這個core檔案到底是哪個程式生成的,可以使用

gdb -c[core 檔名] 來檢視生成此core檔案的程式名。

顯示結果中可以看出程式名,可能像下面這樣

core wasgenerated by `./test'.

之後進入gdb除錯狀態,輸入 where就可以看到程式崩潰時堆疊資訊(當前函式之前的所有已呼叫函式的列表(包括當前函式),我們可以藉此找出是程式中的哪個部分導致了程式崩潰。注意:在編譯程式的時候要加入選項-g。

編譯如下的程式:

#include

using namespace std;

class a

public:

int a;

void fun()

a*t = new a();

t->a = 1;

cout << t->a << endl;

delete t;

delete t;

int main()

fun();

return 0;

執行:

./test

結果為:

*** glibc detected *** ./test: double freeor corruption (fasttop): 0x09fd7008 ***

*****== backtrace: *****====

/lib/libc.so.6[0x3ebe31]

/usr/lib/libstdc++.so.6(_zdlpv+0x22)[0x43fc552]

./test[0x8048705]

./test[0x8048712]

/lib/libc.so.6(__libc_start_main+0xe6)[0x391d26]

./test[0x8048611]

*****== memory map: *****===

00327000-00328000 r-xp 00000000 00:000          [vdso]

00334000-00351000 r-xp 00000000 08:02926955    /lib/libgcc_s-4.4.7-20120601.so.1

00351000-00352000 rw-p 0001d000 08:02926955    /lib/libgcc_s-4.4.7-20120601.so.1

00355000-00373000 r-xp 00000000 08:02926876     /lib/ld-2.12.so

00373000-00374000 r--p 0001d000 08:02926876     /lib/ld-2.12.so

00374000-00375000 rw-p 0001e000 08:02926876     /lib/ld-2.12.so

0037b000-0050c000 r-xp 00000000 08:02926877     /lib/libc-2.12.so

0050c000-0050e000 r--p 00191000 08:02926877     /lib/libc-2.12.so

0050e000-0050f000 rw-p 00193000 08:02926877     /lib/libc-2.12.so

0050f000-00512000 rw-p 00000000 00:00 0

00543000-0056b000 r-xp 00000000 08:02926889     /lib/libm-2.12.so

0056b000-0056c000 r--p 00027000 08:02926889     /lib/libm-2.12.so

0056c000-0056d000 rw-p 00028000 08:02926889     /lib/libm-2.12.so

0434d000-0442e000 r-xp 00000000 08:02155001     /usr/lib/libstdc++.so.6.0.13

0442e000-04432000 r--p 000e0000 08:02155001     /usr/lib/libstdc++.so.6.0.13

04432000-04434000 rw-p 000e4000 08:02155001     /usr/lib/libstdc++.so.6.0.13

04434000-0443a000 rw-p 00000000 00:00 0

09fd7000-09ff8000 rw-p 00000000 00:000          [heap]

b7719000-b771c000 rw-p 00000000 00:00 0

b7727000-b772a000 rw-p 00000000 00:00 0

bfd2a000-bfd3f000 rw-p 00000000 00:000          [stack]

aborted (core dumped)

因為我們對乙個已經delete過了的指標再次delete,所以程式down掉了,可以看到在當前目錄下已經生成了乙個core.4377的檔案,4377就是之前程式啟動的pid。

除錯core檔案:

gdb test core.4377

進入gdb除錯後,鍵入where命令:

(gdb) where

#0 0x00327424 in __kernel_vsyscall ()

#1 0x003a5b11 in raise () from /lib/libc.so.6

#2 0x003a73ea in abort () from /lib/libc.so.6

#3 0x003e59d5 in __libc_message () from /lib/libc.so.6

#4  0x003ebe31in malloc_printerr () from /lib/libc.so.6

#5  0x043fc552 in operator delete(void*) () from/usr/lib/libstdc++.so.6

#6  0x08048705 in fun() ()

#7  0x08048712 in main ()

可以很明顯的看出是在main函式中呼叫fun函式,之後delete指標的時候出錯了,後面的函式呼叫棧就是程式輸出錯誤資訊的部分了,和我們的使用者**無關。到這一步,我們就能推斷是是fun()這個函式中delete某個指標的時候出現了錯誤,就可以有的放矢地查詢具體的問題了。

linux core檔案機制

在程式不尋常退出時,核心會在當前工作目錄下生成乙個core檔案 是乙個記憶體映像,同時加上除錯資訊 使用gdb來檢視core檔案,可以指示出導致程式出錯的 所在檔案和行數。1.core檔案的生成開關和大小限制 1 使用ulimit c命令可檢視core檔案的生成開關。若結果為0,則表示關閉了此功能,...

linux core檔案機制

1.core檔案的生成開關和大小限制 1 使用ulimit c命令可檢視core檔案的生成開關。若結果為0,則表示關閉了此功能,不會生成core檔案。2 使用ulimit c filesize命令,可以限制core檔案的大小 filesize的單位為kbyte 若ulimit c unlimited...

linux core檔案機制

在程式不尋常退出時,核心會在當前工作 目錄下生成乙個core檔案 是乙個記憶體映像,同時加上除錯資訊 使用gdb來檢視core檔案,可以指示出導致程式出錯的 所在檔案和行數。1.core檔案的生成開關和大小限制 1 使用ulimit c命令可檢視core檔案的生成開關。若結果為0,則表示關閉了此功能...