linux core dump 文件 gdb分析


core dump又叫核心轉儲, 當程序運行過程中發生異常, 程序異常退出時, 由操作系統把程序當前的內存狀況存儲在一個core文件中, 叫core dump. (linux中如果內存越界會收到SIGSEGV信號,然后就會core dump)

在程序運行的過程中,有的時候我們會遇到Segment fault(段錯誤)這樣的錯誤。這種看起來比較困難,因為沒有任何的棧、trace信息輸出。該種類型的錯誤往往與指針操作相關。往往可以通過這樣的方式進行定位。

一 造成segment fault,產生core dump的可能原因

1.內存訪問越界

 a) 由於使用錯誤的下標,導致數組訪問越界

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

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

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

使用gdb 調試方法,首先要在gcc編譯時加入-g選項。

調試core文件,在Linux命令行下:gdb pname corefile。

例如,程序名為controller_tester,core文件為core.3421,則為:gdb controller_tester core.3421。

這樣進入了gdb core調試模式。

追蹤產生segmenttation fault的位置及代碼函數調用情況:

 

gdb>bt

這樣,一般就可以看到出錯的代碼是哪一句了,還可以打印出相應變量的數值,進行進一步分析。

gdb>print 變量名

之后,就全看各位自己的編程功力與經驗了,gdb已經做了很多了。

2. 對於結構復雜的程序,如涉及模板類及復雜的調用,gdb得出了出錯位置,似乎這還不夠,這時候要使用更為專業的工具——valgrind。

valgrind是一款專門用作內存調試,內存泄露檢測的開源工具軟件,valgrind這個名字取自北歐神話英靈殿的入口,不過,不能不承認,它確實是Linux下做內存調用分析的神器。一般Linux系統上應該沒有自帶valgrind,需要自行進行下載安裝。

下載地址:http://valgrind.org/downloads/current.html

進入下載文件夾,分別執行(需要root權限,且必須按默認路徑安裝,否則有加載錯誤):

./configure

make

make install

安裝成功后,使用類似如下命令啟動程序:

valgrind --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memchecklog ./controller_test

其中,–log-file=memchecklog指記錄日志文件,名字為memchecklog;–tool=memcheck和–leak-check=full用於內存檢測。

可以得到類似的記錄:

==23735==
==23735== Thread 1:
==23735== Invalid read of size 4
==23735== at 0x804F327: ResourceHandler<HBMessage>::~ResourceHandler() (ResourceHandler.cpp:48)
==23735== by 0x804FDBE: ConnectionManager<HBMessage>::~ConnectionManager() (ConnectionManager.cpp:74)
==23735== by 0×8057288: MainThread::~MainThread() (MainThread.cpp:73)
==23735== by 0x8077B2F: main (Main.cpp:177)
==23735== Address 0×0 is not stack’d, malloc’d or (recently) free’d
==23735==

可以看到說明為無法訪問Address 0x0,明顯為一處錯誤。

這樣valgrind直接給出了出錯原因以及程序中所有的內存調用、釋放記錄,非常智能,在得知錯誤原因的情況下,找出錯誤就效率高多了。

再說一句,valgrind同時給出了程序的Memory Leak情況的報告,給出了new-delete對應情況,所有泄漏點位置給出,這一點在其他工具很難做到,十分好用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM