linux內核學習-調試-coredump的使用

coredump是在程序崩潰後,由linux系統自動收集程序的內存信息並保存到文件的一種機制。如下面所示的提示。
在這裏插入圖片描述
造成這個錯誤的原因有很多,在這邊 博文 有細說。

本文主要講coredump的使用

1.打開coredump

默認情況下,coredump是沒有開啓的,通過命令ulimt -a查看在這裏插入圖片描述
圖中,core file size爲0,

ulimit -c unlimited 

上面的命令表示在程序異常時產生core dump文件,並且不對core dump文件的大小進行限制。
這個命令是當前shell有效的,可以修改.bashrc文件,將命令加入。這樣打開shell就可以自動生效了。

2.設置core文件名命名規則

以上的設置完成後,還需要設置coredump的文件命名規則。
默認情況下,coredump在當前目錄下生成一個叫core的文件。如果有多個程序都發生錯誤,這個core文件是不會覆蓋的。(巨坑!),依然保持最舊的那個。爲了解決這個問題,需要設置coredump的文件命名規則。

echo 'core.%e.%p' > /proc/sys/kernel/core_pattern 

這樣配置後,產生的core文件中將帶有崩潰的程序名、以及它的進程ID。上面的%e和%p會被替換成程序文件名以及進程ID。

可以在core_pattern模板中使用變量還很多,見下面的列表:

%% 單個%字符
%p 所dump進程的進程ID
%u 所dump進程的實際用戶ID
%g 所dump進程的實際組ID
%s 導致本次core dump的信號
%t core dump的時間 (由1970年1月1日計起的秒數)
%h 主機名
%e 程序文件名

如果在上述文件名中包含目錄分隔符”/“,那麼所生成的core文件將會被放到指定的目錄中。

需要說明的是,在內核中還有一個與coredump相關的設置,就是/proc/sys/kernel/core_uses_pid。如果這個文件的內容被配置成1,那麼即使core_pattern中沒有設置%p,最後生成的core dump文件名仍會加上進程ID。

對所生成的core dump進程分析,需要使用調試工具,例如GDB等。

3、調試coredump文件

調試方式爲: gdb program coredump文件

例如我的可執行文件爲test, 生成的coredump文件爲core.3533,則命令如下:

gdb test core.3533
顯示如下圖所示:
在這裏插入圖片描述

嗯,有的人運氣好,直接就顯示源代碼了,如果你像我一樣,接着用下面的命令

backtrace

打印堆棧信息。在這裏插入圖片描述

我們看到最接近崩潰的地方在第8行。也就是你熟悉的代碼的那一行。

然後調用命令

frame 8

直接找到源代碼的位置:
在這裏插入圖片描述

調試第二例

在調試一個“進程的demo“的時候,出現了錯誤,如下

diffork: cxa_atexit.c:100: __new_exitfn: Assertion `l != NULL' failed.
parent gloVar =9,var=32769
diffork: cxa_atexit.c:100: __new_exitfn: Assertion `l != NULL' failed.
已放棄 (核心已轉儲)

這種有錯誤提示的,直接搜一下提示。我就是直接搜提示找到原因的。不過我想看看coredump收集了啥,所以又去看了看coredump。

gdb ./diffork ./core.diffork.102448    執行gdb程序

輸出如下,gdb有提示哪裏出錯了,但是因爲raise.c這個系統源碼文件找不到,所以就顯示不出來。只知道在54行。

Program terminated with signal SIGABRT, Aborted.
#0  0x00007fc48c95c428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
54	../sysdeps/unix/sysv/linux/raise.c: 沒有那個文件或目錄.

打印堆棧,錯誤提示和終端輸出的是一樣的。後來google了下那個錯誤提示,是因爲我vfork的進程沒有正常的exec或exit。改正後,錯誤就沒有了。

(gdb) backtrace
#0  0x00007fc48c95c428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007fc48c95e02a in __GI_abort () at abort.c:89
#2  0x00007fc48c954bd7 in __assert_fail_base (fmt=<optimized out>, 
    assertion=assertion@entry=0x7fc48cab3c58 "l != NULL", 
    file=file@entry=0x7fc48cab3c4b "cxa_atexit.c", line=line@entry=100, 
    function=function@entry=0x7fc48cab7348 <__PRETTY_FUNCTION__.7638> "__new_exitfn") at assert.c:92
#3  0x00007fc48c954c82 in __GI___assert_fail (
    assertion=0x7fc48cab3c58 "l != NULL", file=0x7fc48cab3c4b "cxa_atexit.c", 
    line=100, 
    function=0x7fc48cab7348 <__PRETTY_FUNCTION__.7638> "__new_exitfn")
    at assert.c:101
#4  0x00007fc48c961228 in __new_exitfn (
    listp=listp@entry=0x7fc48cceb5f8 <__exit_funcs>) at cxa_atexit.c:100
#5  0x00007fc48c961299 in __internal_atexit (
    listp=0x7fc48cceb5f8 <__exit_funcs>, d=0x0, arg=0x0, func=0x1b)
    at cxa_atexit.c:35
#6  __GI___cxa_atexit (func=0x1b, arg=arg@entry=0x0, d=d@entry=0x0)
    at cxa_atexit.c:58
#7  0x00007fc48c947793 in __libc_start_main (main=0x400636 <main>, argc=1, 
    argv=0x7fff101df7c8, init=0x400750 <__libc_csu_init>, 
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff101df7b8)
---Type <return> to continue, or q <return> to quit--- 
    at ../csu/libc-start.c:221
#8  0x0000000000400569 in _start ()

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