linux下coredump的產生及調試方法

什麼是coredumplinux

一般狀況下coredmp包括了程序執行時的內存,寄存器狀態,堆棧指針,內存管理信息等。可以理解爲把程序工做的當前狀態存儲成一個文件。不少程序和操做系統出錯時會本身主動生成一個core文件。數組

怎樣使用coredump安全

coredump可以用在很是多場合,使用Linux,或者solaris的人可能都有過這樣的經歷,系統在跑一些壓力測試或者系統負載一大的話,系統就hang住了或者乾脆system panic.這時惟一能幫助你分析和解決這個問題的就是coredump了。bash

現在很是多應該程序出錯時也會出現coredump.多線程

分析coredump的工具函數

現在大部分類unix操做系統都提供了分析core文件的工具,比方 GNU Binutils Binary File Descriptor library (BFD), GNU Debugger (gdb),mdb工具

coredump的文件格式ui

類unix操做系統中使用efi格式保存coredump文件。spa

在solairs下操作系統

bash-3.2# file *unix.3 ELF 32-bit LSB executable 80386 Version 1, statically linked, not stripped, no debugging information availableunix.4 ELF 32-bit LSB executable 80386 Version 1, statically linked, not stripped, no debugging information available

形成程序coredump的緣由很是多,這裏依據以往的經驗總結一下:

1 內存訪問越界
  a) 由於使用錯誤的下標,致使數組訪問越界
  b) 搜索字符串時,依靠字符串結束符來推斷字符串是否結束,但是字符串沒有正常的使用結束符
  c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操做函數,將目標字符串讀/寫爆。應該使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函數防止讀寫越界。

2 多線程程序使用了線程不安全的函數。
應該使用如下這些可重入的函數,尤爲注意紅色標示出來的函數,它們很是easy被用錯:
asctime_r(3c) gethostbyname_r(3n) getservbyname_r(3n) ctermid_r(3s) gethostent_r(3n) getservbyport_r(3n) ctime_r(3c) getlogin_r(3c) getservent_r(3n) fgetgrent_r(3c) getnetbyaddr_r(3n) getspent_r(3c) fgetpwent_r(3c) getnetbyname_r(3n) getspnam_r(3c) fgetspent_r(3c) getnetent_r(3n) gmtime_r(3c) gamma_r(3m) getnetgrent_r(3n) lgamma_r(3m) getauclassent_r(3) getprotobyname_r(3n) localtime_r(3c) getauclassnam_r(3) etprotobynumber_r(3n) nis_sperror_r(3n) getauevent_r(3) getprotoent_r(3n) rand_r(3c) getauevnam_r(3) getpwent_r(3c) readdir_r(3c) getauevnum_r(3) getpwnam_r(3c) strtok_r(3c) getgrent_r(3c) getpwuid_r(3c) tmpnam_r(3s) getgrgid_r(3c) getrpcbyname_r(3n) ttyname_r(3c) getgrnam_r(3c) getrpcbynumber_r(3n) gethostbyaddr_r(3n) getrpcent_r(3n)

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

4 非法指針
  a) 使用空指針
  b) 任意使用指針轉換。一個指向一段內存的指針,除非肯定這段內存原先就分配爲某種結構或類型,或者這樣的結構或類型的數組,不然不要將它轉換爲這樣的結構或類型 的指針,而應該將這段內存複製到一個這樣的結構或類型中,再訪問這個結構或類型。這是因爲假設這段內存的開始地址不是依照這樣的結構或類型對齊的,那麼訪問它 時就很是easy因爲bus error而core dump.

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

coredump文件的生成方法以及用法:

(若是下例是在x86上交叉編譯,而在arm上執行異常的現象)

1. arm內核裏添�coredump的支持(通常內核都支持coredump, 不用重編)

2. 執行命令,此時贊成coredump文件產生:(arm)
ulimit –c unlimited

3. 運行程序:(在arm上)
./test
在異常退出時,會顯演示樣例如如下信息,注意括號中的內容
Segmentation fault (core dumped)
程序運行文件夾下將產生*core文件

4. gdb分析:(在x86上)
arm-linux-gdb ./test test.core
再用gdbbtwhere看就可以了
(arm-linux-gdb
的編譯見<調試工具之四gdbserve>)


系統支持生成core並設置存儲位置的方法:

1> 在/etc/profile中添�下面一行,這將贊成生成coredump文件 ulimit -c unlimited 2> 在rc.local中添�下面一行,這將使程序崩潰時生成的coredump文件位於/tmp文件夾下: echo /tmp/core.%e.%p > /proc/sys/kernel/core_pattern  /tmp/也可以是其餘的文件夾位置。最佳位置應當知足下面需求: * 對所有用戶可寫 * 空間容量足夠大 * 掉電後文件不丟失

相關文章
相關標籤/搜索