什麼是coredump?html
Coredump叫作核心轉儲,它是進程運行時在忽然崩潰的那一刻的一個內存快照。操做系統在程序發生異常而異常在進程內部又沒有被捕獲的狀況下,會把進程此刻內存、寄存器狀態、運行堆棧等信息轉儲保存在一個文件裏。linux
該文件也是二進制文件,可使用gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb進行打開分析裏面的具體內容。
redis
ulimit -c 能夠設置core文件的大小,若是這個值爲0.則不會產生core文件,這個值過小,則core文件也不會產生,由於core文件通常都比較大。windows
使用ulimit -c unlimited來設置無限大,則任意狀況下都會產生core文件。sass
ulimit -a能夠查看當前core文件限制。app
一、設置core文件的名稱和文件路徑
默認生成路徑:輸入可執行文件運行命令的同一路徑下
默認生成名字:默認命名爲core。新的core文件會覆蓋舊的core文件函數
a.設置pid做爲文件擴展名
1:添加pid做爲擴展名,生成的core文件名稱爲core.pid
0:不添加pid做爲擴展名,生成的core文件名稱爲core
修改 /proc/sys/kernel/core_uses_pid 文件內容爲: 1
修改文件命令: echo "1" > /proc/sys/kernel/core_uses_pid
或者
sysctl -w kernel.core_uses_pid=1 kernel.core_uses_pid = 1ui
二、控制core文件保存位置和文件名格式
修改文件命令: echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
或者:
sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t kernel.core_pattern = /corefile/core-%e-%p-%t
能夠將core文件統一輩子成到/corefile目錄下,產生的文件名爲core-命令名-pid-時間戳
如下是參數列表:
%p - insert pid into filename 添加pid(進程id)
%u - insert current uid into filename 添加當前uid(用戶id)
%g - insert current gid into filename 添加當前gid(用戶組id)
%s - insert signal that caused the coredump into the filename 添加致使產生core的信號
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成時的unix時間
%h - insert hostname where the coredump happened into filename 添加主機名
%e - insert coredumping executable name into filename 添加致使產生core的命令名
spa
gdb 調試coredump的簡單示例操作系統
#include "stdio.h" #include "stdlib.h" void dumpCrash() { char *ptr = "test"; free(ptr); } int main() { dumpCrash(); return 0; }
如上代碼,pStr指針指向的是字符串常量,字符串常量是保存在常量區的,free釋放常量區的內存確定會致使coredump。
gcc -o dump test.c
運行test產生core文件,接下來利用gdb來調試coredump。
一、查看coredump時的堆棧。查看堆棧使用bt或者where命令
二、未gcc -g的話,沒有調試信息的狀況下,打開coredump堆棧,並不會直接顯示core的代碼行。
此時,frame addr(幀數)或者簡寫以下,f 4 跳轉到core堆棧的第1幀。由於第0幀,1幀,2幀,3幀都是libc的代碼,已經不是咱們本身代碼了。disassemble打開該幀函數的反彙編代碼。
以下箭頭(紅標)位置表示coredump時該函數調用所在的位置
[root@tlinux /]# gdb dump(文件名) core.89056
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>;...
Reading symbols from /dump...(no debugging symbols found)...done.
[New LWP 89056]
Core was generated by `./dump'.
Program terminated with signal 6, Aborted.
#0 0x00007f2c4e1a8277 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.el7.x86_64 libgcc-4.8.5-36.el7.x86_64
(gdb) bt
#0 0x00007f2c4e1a8277 in raise () from /lib64/libc.so.6
#1 0x00007f2c4e1a9968 in abort () from /lib64/libc.so.6
#2 0x00007f2c4e1ead37 in __libc_message () from /lib64/libc.so.6
#3 0x00007f2c4e1f3499 in _int_free () from /lib64/libc.so.6
#4 0x0000000000400539 in dumpCrash ()
#5 0x0000000000400549 in main ()
(gdb) f 4
#4 0x0000000000400539 in dumpCrash ()
(gdb) disassemble
Dump of assembler code for function dumpCrash:
0x000000000040051d <+0>: push %rbp
0x000000000040051e <+1>: mov %rsp,%rbp
0x0000000000400521 <+4>: sub $0x10,%rsp
0x0000000000400525 <+8>: movq $0x4005e0,-0x8(%rbp)
0x000000000040052d <+16>: mov -0x8(%rbp),%rax
0x0000000000400531 <+20>: mov %rax,%rdi
0x0000000000400534 <+23>: callq 0x400400 <free@plt>
=> 0x0000000000400539 <+28>: leaveq
0x000000000040053a <+29>: retq
End of assembler dump.
(gdb)
不過上面的free使用去掉名詞修飾效果和以前仍是同樣的。可是咱們能夠推測到這裏是在調用free函數。
如此,咱們就能知道咱們coredump的位置,從而進一步能推斷出coredump的緣由。
固然,現實環境中,coredump的場景確定遠比這個複雜,都是邏輯都是同樣的,咱們須要先找到coredump的位置,再結合代碼以及core文件推測coredump的緣由。