gdb調試core dump使用
什麽是coredump?
Coredump叫做核心轉儲,它是進程運行時在突然崩潰的那一刻的一個內存快照。操作系統在程序發生異常而異常在進程內部又沒有被捕獲的情況下,會把進程此刻內存、寄存器狀態、運行堆棧等信息轉儲保存在一個文件裏。
該文件也是二進制文件,可以使用gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb進行打開分析裏面的具體內容。
ulimit -c 可以設置core文件的大小,如果這個值為0.則不會產生core文件,這個值太小,則core文件也不會產生,因為core文件一般都比較大。
使用ulimit -c unlimited來設置無限大,則任意情況下都會產生core文件。
ulimit -a可以查看當前core文件限制。
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。
1、查看coredump時的堆棧。查看堆棧使用bt或者where命令
2、未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的原因。
gdb調試core dump使用