core dump
通常情況下coredmp包含了程序運行時的內存,寄存器狀態,堆棧指針,內存管理信息等??梢岳斫鉃榘殉绦蚬ぷ鞯漠斍盃顟B存儲成一個文件。許多程序和操作系統出錯時會自動生成一個core文件。
如何使用coredump?coredump可以用在很多場合,使用Linux,或者solaris的人可能都有過這種經歷,系統在跑一些壓力測試或者系統負載一大的話,系統就hang住了或者干脆system panic.這時唯一能幫助你分析和解決問題的就是coredump了。現在很多應該程序出錯時也會出現coredump.
分析coredump的工具現在大部分類unix操作系統都提供了分析core文件的工具,比如 GNU Binutils Binary File Descriptor library (BFD), GNU Debugger (gdb),mdb等coredump的文件格式類unix操作系統中使用efi格式保存coredump文件。在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 多線程程序使用了線程不安全的函數。應該使用下面這些可重入的函數,尤其注意紅色標示出來的函數,它們很容易被用錯: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 多線程讀寫的數據未加鎖保護。對于會被多個線程同時訪問的全局數據,應該注意加鎖保護,否則很容易造成core dump?4 非法指針? a) 使用空指針? b) 隨意使用指針轉換。一個指向一段內存的指針,除非確定這段內存原先就分配為某種結構或類型,或者這種結構或類型的數組,否則不要將它轉換為這種結構或類型 的指針,而應該將這段內存拷貝到一個這種結構或類型中,再訪問這個結構或類型。這是因為如果這段內存的開始地址不是按照這種結構或類型對齊的,那么訪問它 時就很容易因為bus error而core dump.?5 堆棧溢出不要使用大的局部變量(因為局部變量都分配在棧上),這樣容易造成堆棧溢出,破壞系統的棧和堆結構,導致出現莫名其妙的錯誤。?coredump文件的生成方法以及使用方法:1. ?運行命令,此時允許coredump文件產生:?ulimit –c unlimited2. ?執行程序:./test在異常退出時,會顯示如下信息,注意括號里的內容Segmentation fault (core dumped)程序執行目錄下將產生*core文件3. ?用gdb分析:#gdb ./test test.core系統支持生成core并設置存儲位置的方法:1> 在/etc/profile中加入以下一行,這將允許生成coredump文件ulimit -c unlimited
ulimit -c 1024 #Kb
ulimit -c 0 #不產生core file
2> 在rc.local中加入以下一行,這將使程序崩潰時生成的coredump文件位于/tmp目錄下:echo /tmp/core.%e.%p > /proc/sys/kernel/core_pattern ?說明:以下是參數列表:
? ? %p - insert pid into filename 添加pid
? ? %u - insert current uid into filename 添加當前uid
? ? %g - insert current gid into filename 添加當前gid
? ? %s - insert signal that caused the coredump into the filename 添加導致產生core的信號
? ? %t - insert UNIX time that the coredump occurred into filename 添加core文件生成時的unix時間
? ? %h - insert hostname where the coredump happened into filename 添加主機名
? ? %e - insert coredumping executable name into filename 添加命令名
* 掉電后文件不丟失
* 掉電后文件不丟失
一個小列子
/** description: 演示core dump使用,這里產生一個 senmengtation fault #ulimit -c unlimited* compile with: gcc -g -o test test.c*/#include<stdio.h> int main(int argc, char *argv[]) {char *p = NULL;printf("test a error: %s\n",*p);return 0; }總結
- 上一篇: Linux生成随机字符串
- 下一篇: 我堕落了~~