一、core dump
1.何謂 core dump?
在使用半導體作爲內存的材料前,人類是利用線圈當作內存的材料,線圈就叫作 core ,用線圈做的內存就叫作core memory。如今,半導體工業澎勃發展,已經沒有人用core memory 了,不過,在許多情況下,人們還是把記憶體叫作core 。
我們在開發(或使用)一個程序時,最怕的就是程序莫明其妙地當掉。雖然系統沒事,但我們下次仍可能遇到相同的問題。於是這時操作系統就會把程序當掉 時的內存內容 dump 出來(現在通常是寫在一個叫 core的file裏面),讓 我們或是debugger 做爲參考。這個動作就叫作 core dump。
在 C/C++語言中,最常發生錯誤的地方就是指 針有問題。您可以利用 core 文件和debugger工具(gdb)把錯誤找出來。除了SIGSEGV(無效內存訪問)信號以外,SIGABRT(異常終止), SIGBUS(硬件故障),SIGEMT(硬件故障),SIGFPE(算術異常),SIGILL(非法硬件指令),SIGIOT(硬件故障),SIGQUIT,SIGSYS(無效系統調用),SIGTRAP(硬件故障)等。
2.設置core dump
如果完全用不到調試程序,那麼用不到核心轉儲功能。
要怎麼纔不會讓 core 文件出現
如果用的是bash的話, 在/etc/profile里加上(或者修改)一條:
ulimit -c 0
如果想讓系統在信號中斷造成的錯誤時產生core文件, 我們需要在shell中按如下設置:
首先查看一下現在的設置: #ulimit -a
#ulimit -c unlimited #設置core大小爲無限
#ulimit unlimited #設置文件大小爲無限
有些系統發行版本沒有默認開啓core dump功能,需要將上面的命令加入shell的配置文件,例如~/.bashrc。如果要加入全局配置文件/etc/profile中,這些需要有root權限。
配置生成core文件的相關參數/proc/sys/kernel/core_uses_pid文件可以控制core文件的文件名是否以pid作爲擴展。如果文件內容爲1表示添加pid作爲擴展,生成core文件的格式爲core.xxx;爲0表示生成的core文件與運行的程序同名。
/proc/sys/kernel/core_pattern文件可以控制core文件保存位置和文件名格式,例如
#echo "/corefile/core-e%-%p-%t" > /proc/sys/kernel/core_pattern
#mkdir /corefile
則保存路徑是~/corefile,格式是core-命令名-pid-時間戳 ,其他參數:
%u current uid
%g current gid
%s insert signal that caused the coredump
%h host name where the coredump occurred
二、gdb調試簡介
(1).GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
· Start your program, specifying anything that might affect its behavior.
· Make your program stop on specified conditions.
· Examine what has happened, when your program has stopped.
· Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.
(2).start GDB
$gdb
$gdb program
$gdb program core
$gdb program proc-pid #attch GDB to process proc-pid(unless you also have a core file same name as proc-pid; GDB check for a core dump file firsts)
(3). frenquently GDB commands
break or b[file:]function Set a breakpoint at function (in file). e.g.b main
run or r [arglist] Start your program (with arglist, if specified).
bt Backtrace: display the program stack.
print expr Display the value of an expression.
c Continue running your program (after stopping,e.g. at a breakpoint).
next or n Execute next program line (after stopping);step over any function calls in the line.
edit [file:]function look at the program line where it is presently stopped.
list [file:]function type the text of the program in the vicinity of where it is presently stopped.
step or s Execute next program line (after stopping); step into any function calls in the line.
help [name] Show information about GDB command name, or general information about using GDB.
set width 70 #設置標準屏幕爲70列
quit or q Exit from GDB.
for example:
//test.c
(gdb) b main
Breakpoint 1 at 0x400534: file test.c, line 19.
(gdb) b func1
Breakpoint 2 at 0x400524: file test.c, line 13.
(gdb) r
Starting program: /home/luffy/workspace/myapue/test
Breakpoint 1, main () at test.c:19
19 func1(); #noted that the next line is calling a function named func1
(gdb) l #list the current location
14 }
15
16 int
17 main()
18 {
19 func1();
20 return 0;
21 }
(gbd) s #step into func1
Breakpoint 2, func1 () at test.c:13
13 func();
(gbd) l 5 #let's have a view of this func
10 void
11 func1()
12 {
13 func();
14 }
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400508 in func () at test.c:7
7 printf("%d\n", *p);
(gdb) bt
...show informations about stack...
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) q
另外,print可以顯示當前變量的內容。例如p int_var, array_var或struct_var等等。
三、core dump調試技術
1. 爲了使用gdb進行程序調試,需要在編譯程序中加入供gdb使用的調試信息。方法是在
編譯程序時使用:
-g gdb輸出debug調試信息
-DDEBUG 傳入宏DEBUG
-UDEBUG 取消宏DEBUG
舉例如下
利用gcc的 -DDEBUG選項。
(1).源文件DEBUG.c中有:
#include <stdio.h>
int main(int argc, char *argv[])
{
#ifdef DEBUG
printf("DEBUG is definded \n");
#else
printf("DEBUG is not definded \n");
#endif
}
(2). 輸入:$gcc -g -o debug DEBUG.c
$./debug
out: DEBUG is not definded
(3). 輸入:$gcc -DDEBUG -g -o debug DEBUG.c
$./debug
out: DEBUG is definded
release版本編譯
除去 -g -DDEBUG,並且加上 -o3 : 最大優化代碼
2. 一個簡單的例子
//test.c
#include <stdio.h>
void
func()
{
int *p = NULL;
printf(
"%d\n", *p);
}
int
main()
{
func();
return 0;
}
$gcc -g -o test test.c
$./test.c
out:段錯誤(核心已轉儲)
如果沒有轉儲,是因爲默認選項的問題。通過echo "ulimit -S -c unlimited > /dev/null 2>&1" >>~/.bashrc,然後應用該配置文件. ~/.bashrc即可。
3. 直接從core文件裏獲得出錯信息,有
$gdb -c core
$ gdb -c core-e3926-1311507364
......
[New Thread 3926]
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
(gdb) bt
#0 0x0000000000400508 in ?? ()
#1 0x0000000000000000 in ?? ()
(gdb) q
有時候並不能獲得有效信息。
4. 用gdb查看core文件:
下面我們可以在發生運行時信號引起的錯誤時發生core dump了.
發生core dump之後, 用gdb進行查看core文件的內容, 以定位文件中引發core dump的行.
gdb [exec file] [core file]
或者gdb --core=[core file] [exec file]或者gdb -c [core file] [exec file]
如:
gdb ./test test.core
在進入gdb後, 用bt(backtrace: display the program stack)命令查看backtrace以檢查發生程序運行到哪裏, 來定位core dump的文件->行.
Core was generated by `./test.o'.
Program terminated with signal 11, Segmentation fault.
#0 0x0000000000400508 in func () at test.c:7
7 printf("%d\n", *p);
(gdb) bt
#0 0x0000000000400508 in func () at test.c:7
#1 0x000000000040052e in main () at test.c:13
(gdb) q
Reference:
APUE
man gdb
Linux core dump file http://apps.hi.baidu.com/share/detail/30247650
Linux下使用core文件調試程序 http://www.docin.com/p-235044288.html
gdb簡介 http://www.360doc.com/content/07/0119/10/4910_336656.shtml