意外的崩潰,在日志沒法有效支撐時,core dumped是一種有效的調試方法。linux的core-dump默認是關閉的,在使用時,我們需要作以下設置:
1)設置 core 的存儲目錄和命名格式
主要是修改配置文件 /proc/sys/kernel/core_pattern
# 1. 默認在當前程序執行目錄下生成,core-程序名-程序pid-時間 [core-test-3451-1516257740] [root@ ~]# echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern # 2. 添加路徑,可以把所有的 core 集中到一個文件夾里 [把所有的core文件放到 /root/core-file 目錄下] [root@ ~]# echo "/root/core-file/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
要保證運行的程序對該目錄具有寫權限。
2)將core file的大小限制取消掉。相關命令是ulimit
// 輸入目錄查看狀態, 0 說明是禁止生成 core 文件。
[root@ ~]# ulimit -c 0
我們可以直接在 ulimit -c
后面加上參數,當為數字時表示限制 core 文件大小不超過 1024KB[ulimit -c 1024
]。但是在實際使用中一般不會設置一個固定的core大小限制。如下:
# unlimited: 字面意思,沒有限制 core 文件大小。 [root@ ~]# ulimit -c unlimited # 有些系統上,非root用戶執行可能會失敗,為了方便操作這里都使用root用戶。
3)執行能產生core dump的程序。
這邊提供一個例子使用 gcc -g test.c -o test進行編譯。
// FILE:test.c
#include<stdlib.h>
void repeatFree(char *p) { if(NULL != p) { free(p); } } int main() { char* pstr =(char*) malloc(10); repeatFree(pstr); // 第一次釋放
repeatFree(pstr); // 第二次釋放
return 0; }
[root@ ~]# ~/Workspace/logDemo/build$ ./test free(): double free detected in tcache 2 Aborted (core dumped)
崩潰后core dumped 信息代表 相關的core文件已經產生了。
4)使用gdb對core文件崩潰信息進行還原:
- gdb test core-test-1806-1646101790
- 輸入where命令可以看到導致崩潰的代碼所在行數
[root@ ~]#/Workspace/logDemo/build$ gdb test core-test-1806-1646101790 GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from testg...done. [New LWP 1806] Core was generated by `./test'.
Program terminated with signal SIGABRT, Aborted. #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) where #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007f07e70a8921 in __GI_abort () at abort.c:79 #2 0x00007f07e70f1967 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f07e721eb0d "%s\n") at ../sysdeps/posix/libc_fatal.c:181 #3 0x00007f07e70f89da in malloc_printerr (str=str@entry=0x7f07e7220778 "free(): double free detected in tcache 2") at malloc.c:5342 #4 0x00007f07e710020d in _int_free (have_lock=0, p=0x557ad2529250, av=0x7f07e7453c40 <main_arena>) at malloc.c:4195 #5 __GI___libc_free (mem=0x557ad2529260) at malloc.c:3134 #6 0x0000557ad1e0a6a9 in repeatFree (p=0x557ad2529260 "") at test.c:8 #7 0x0000557ad1e0a6da in main () at test.c:18 (gdb)
注:在第3步在編譯時使用了-g的選項, 只有在使用-g編譯選項編譯的程序,在gdb環境下輸入where才能顯示具體的行號。至於一個程序是否使用了-g選項可以使用file命令進行查看。
如下:
#使用-g選項編譯的程序 [root@ ~]# file testg testg: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=ffd3e3fbe1964dccfe1a43f477613cb9814667fa, with debug_info, not stripped #使用不帶-g選項編譯的程序 [root@ ~]# file test_ test_: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=9057778da9314e9625bf2f4e8d05fe79907b1282, not stripped
使用-g選項編譯的程序在使用file命令查看時,帶有with debug_info信息。該信息在使用core調試時候具有關鍵的作用。使之可以顯示導致崩潰的行號。