GDB & core dump

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