core dump
通常情況下coredmp包含了程序運(yùn)行時(shí)的內(nèi)存,寄存器狀態(tài),堆棧指針,內(nèi)存管理信息等。可以理解為把程序工作的當(dāng)前狀態(tài)存儲(chǔ)成一個(gè)文件。許多程序和操作系統(tǒng)出錯(cuò)時(shí)會(huì)自動(dòng)生成一個(gè)core文件。
如何使用coredump?coredump可以用在很多場(chǎng)合,使用Linux,或者solaris的人可能都有過(guò)這種經(jīng)歷,系統(tǒng)在跑一些壓力測(cè)試或者系統(tǒng)負(fù)載一大的話,系統(tǒng)就hang住了或者干脆system panic.這時(shí)唯一能幫助你分析和解決問(wèn)題的就是coredump了。現(xiàn)在很多應(yīng)該程序出錯(cuò)時(shí)也會(huì)出現(xiàn)coredump.
分析coredump的工具現(xiàn)在大部分類(lèi)unix操作系統(tǒng)都提供了分析core文件的工具,比如 GNU Binutils Binary File Descriptor library (BFD), GNU Debugger (gdb),mdb等coredump的文件格式類(lèi)unix操作系統(tǒng)中使用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的原因很多,這里根據(jù)以往的經(jīng)驗(yàn)總結(jié)一下:1 內(nèi)存訪問(wèn)越界? a) 由于使用錯(cuò)誤的下標(biāo),導(dǎo)致數(shù)組訪問(wèn)越界? b) 搜索字符串時(shí),依靠字符串結(jié)束符來(lái)判斷字符串是否結(jié)束,但是字符串沒(méi)有正常的使用結(jié)束符? c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函數(shù),將目標(biāo)字符串讀/寫(xiě)爆。應(yīng)該使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函數(shù)防止讀寫(xiě)越界。?2 多線程程序使用了線程不安全的函數(shù)。應(yīng)該使用下面這些可重入的函數(shù),尤其注意紅色標(biāo)示出來(lái)的函數(shù),它們很容易被用錯(cuò):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 多線程讀寫(xiě)的數(shù)據(jù)未加鎖保護(hù)。對(duì)于會(huì)被多個(gè)線程同時(shí)訪問(wèn)的全局?jǐn)?shù)據(jù),應(yīng)該注意加鎖保護(hù),否則很容易造成core dump?4 非法指針? a) 使用空指針? b) 隨意使用指針轉(zhuǎn)換。一個(gè)指向一段內(nèi)存的指針,除非確定這段內(nèi)存原先就分配為某種結(jié)構(gòu)或類(lèi)型,或者這種結(jié)構(gòu)或類(lèi)型的數(shù)組,否則不要將它轉(zhuǎn)換為這種結(jié)構(gòu)或類(lèi)型 的指針,而應(yīng)該將這段內(nèi)存拷貝到一個(gè)這種結(jié)構(gòu)或類(lèi)型中,再訪問(wèn)這個(gè)結(jié)構(gòu)或類(lèi)型。這是因?yàn)槿绻@段內(nèi)存的開(kāi)始地址不是按照這種結(jié)構(gòu)或類(lèi)型對(duì)齊的,那么訪問(wèn)它 時(shí)就很容易因?yàn)閎us error而core dump.?5 堆棧溢出不要使用大的局部變量(因?yàn)榫植孔兞慷挤峙湓跅I?#xff09;,這樣容易造成堆棧溢出,破壞系統(tǒng)的棧和堆結(jié)構(gòu),導(dǎo)致出現(xiàn)莫名其妙的錯(cuò)誤。?coredump文件的生成方法以及使用方法:1. ?運(yùn)行命令,此時(shí)允許coredump文件產(chǎn)生:?ulimit –c unlimited2. ?執(zhí)行程序:./test在異常退出時(shí),會(huì)顯示如下信息,注意括號(hào)里的內(nèi)容Segmentation fault (core dumped)程序執(zhí)行目錄下將產(chǎn)生*core文件3. ?用gdb分析:#gdb ./test test.core系統(tǒng)支持生成core并設(shè)置存儲(chǔ)位置的方法:1> 在/etc/profile中加入以下一行,這將允許生成coredump文件ulimit -c unlimited
ulimit -c 1024 #Kb
ulimit -c 0 #不產(chǎn)生core file
2> 在rc.local中加入以下一行,這將使程序崩潰時(shí)生成的coredump文件位于/tmp目錄下:echo /tmp/core.%e.%p > /proc/sys/kernel/core_pattern ?說(shuō)明:以下是參數(shù)列表:
? ? %p - insert pid into filename 添加pid
? ? %u - insert current uid into filename 添加當(dāng)前uid
? ? %g - insert current gid into filename 添加當(dāng)前gid
? ? %s - insert signal that caused the coredump into the filename 添加導(dǎo)致產(chǎn)生core的信號(hào)
? ? %t - insert UNIX time that the coredump occurred into filename 添加core文件生成時(shí)的unix時(shí)間
? ? %h - insert hostname where the coredump happened into filename 添加主機(jī)名
? ? %e - insert coredumping executable name into filename 添加命令名
* 掉電后文件不丟失
* 掉電后文件不丟失
一個(gè)小列子
/** description: 演示core dump使用,這里產(chǎn)生一個(gè) 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; }總結(jié)
- 上一篇: Linux生成随机字符串
- 下一篇: 我堕落了~~