GDB調試core文件樣例(如何定位Segment fault) 【轉】

core dump又叫核心轉儲, 當程序運行過程當中發生異常, 程序異常退出時, 由操做系統把程序當前的內存情況存儲在一個core文件中, 叫core dump. (linux中若是內存越界會收到SIGSEGV信號,而後就會core dump)html

在程序運行的過程當中,有的時候咱們會遇到Segment fault(段錯誤)這樣的錯誤。這種看起來比較困難,由於沒有任何的棧、trace信息輸出。該種類型的錯誤每每與指針操做相關。每每能夠經過這樣的方式進行定位。linux

一 形成segment fault,產生core dump的可能緣由shell

1.內存訪問越界小程序

 a) 因爲使用錯誤的下標,致使數組訪問越界數組

 b) 搜索字符串時,依靠字符串結束符來判斷字符串是否結束,可是字符串沒有正常的使用結束符安全

 c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操做函數,將目標字符串讀/寫爆。應該使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函數防止讀寫越界。bash

2 多線程程序使用了線程不安全的函數。多線程

3 多線程讀寫的數據未加鎖保護。對於會被多個線程同時訪問的全局數據,應該注意加鎖保護,不然很容易形成core dump函數

4 非法指針測試

a) 使用空指針

b) 隨意使用指針轉換。一個指向一段內存的指針,除非肯定這段內存原先就分配爲某種結構或類型,或者這種結構或類型的數組,不然不要將它轉換爲這種結構或類型 的指針,而應該將這段內存拷貝到一個這種結構或類型中,再訪問這個結構或類型。這是由於若是這段內存的開始地址不是按照這種結構或類型對齊的,那麼訪問它 時就很容易由於bus error而core dump.

5 堆棧溢出.不要使用大的局部變量(由於局部變量都分配在棧上),這樣容易形成堆棧溢出,破壞系統的棧和堆結構,致使出現莫名其妙的錯誤。

二 配置操做系統使其產生core文件

首 先經過ulimit命 令查看一下系統是否配置支持了dump core的功能。經過ulimit -c或ulimit -a,能夠查看core file大小的配置狀況,若是爲0,則表示系統關閉了dump core。能夠經過ulimit -c unlimited來打開。若發生了段錯誤,但沒有core dump,是因爲系統禁止core文件的生成。

解決方法:
$ulimit -c unlimited  (只對當前shell進程有效)
或在~/.bashrc 的最後加入: ulimit -c unlimited (一勞永逸)

# ulimit -c

0

 

$ ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

file size               (blocks, -f) unlimited

三 用gdb查看core文件

發生core dump以後, 用gdb進行查看core文件的內容, 以定位文件中引起core dump的行.

gdb [exec file] [core file]

如: gdb ./test test.core

 

四 樣例

 

1. 空指針

樣例:

#include <stdio.h>

int main(void)

{

    printf("hello world! dump core for set value to NULL pointer/n");

    *(char *)0 = 0;

    return 0;

}

# gcc -g test.c -o test

# ./test

hello world! dump core for set value to NULL pointer

Segmentation fault    

/× Get segmentation fault, but there is no core dump. The reason is that the system configure core file size to zero ×/

# ls

test  test.c

/* Set core file size to unlimited */

# ulimit -c unlimited

# ./test

hello world! dump core for set value to NULL pointer

Segmentation fault (core dumped)

/* Get core dump after change core file size. */

# ls

core.5581  test  test.c

/* gdb to debug core dump */

# gdb test core.5581
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".

Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib64/tls/libc.so.6...done.
Loaded symbols for /lib64/tls/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
#0  0x000000000040048b in main () at test.c:6

warning: Source file is more recent than executable.

6           *(char *)0 = 0;
(gdb) bt
#0  0x000000000040048b in main () at test.c:6
 

2. 棧溢出。

有關棧溢出的程序,請參見:一個測試棧大小的小程序

http://blog.163.com/huang_bp/blog/static/12311983720099150746901/edit/

 

 

# gcc -g test.c -o test -lpthread

# ls

test  test.c

# ./test

...

Segmentation fault (core dumped)

# ls

core.5616  test  test.c

# gdb test core.5616
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".

Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib64/tls/libpthread.so.0...done.
Loaded symbols for /lib64/tls/libpthread.so.0
Reading symbols from /lib64/tls/libc.so.6...done.
Loaded symbols for /lib64/tls/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
#0  0x0000002a957c051e in vfprintf () from /lib64/tls/libc.so.6
(gdb) list
13
14         buffer[0]=i;
15          test(s);
16      }
17
18      int   main()
19      {
20          pthread_t p;
21
22          pthread_create(&p, NULL, &test, NULL);

對於棧溢出的segment fault沒有第一個定位方便,須要分析代碼才能判斷出緣由。

================================================================
推薦參考:
Linux下的段錯誤產生的緣由及調試方法
轉自:http://blog.csdn.net/sunboy_2050/article/details/5945152
相關文章
相關標籤/搜索