linux 下除錯coredump檔案
1、coredump簡介
在linux後臺開發過程中可能一不小心出現訪問非法記憶體而產生段錯誤,面對段錯誤我們有時候可以通過列印定位,但那樣比較慢,我們可以利用linux提供了一種方法,當程式奔潰時核心會儲存程式執行的堆疊資訊到一個coredump檔案,我們可以通過gdb除錯這個coredump檔案可以知道程式死之前呼叫了那個函式。
2、開啟coredump
我們通過ulimit -c檢視系統是否開啟了core dump功能,如果輸出是0表示沒有開,開啟coredump檔案的命令是ulimit -c unlimited,unlimited表示不限制core dump檔案的大小,這樣可以保全堆疊資訊,開啟coredump功能編譯程式時不能通過trip去掉程式連線的符號表資訊,不然通過gdb除錯時連線不要符號表。我們還可以指定產生coredump檔案的位置和格式,
命令:echo "/home/core-%e-%p-%t" > /proc/sys/kernel/core_pattern 這樣設定coredump檔案的儲存在/home目錄下,檔名格式是core-程序名-程序pid-時間戳。
3、系統介面
coredump設定的介面是setrlimit,主要是設定rlimit結構體
//獲取rlimit int getrlimit(int resource, struct rlimit *rlim); //設定rlimit int setrlimit(int resource, const struct rlimit *rlim);
struct rlimit {
rlim_t rlim_cur; /* Soft limit 軟體設定值*/
rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur)硬體支援最大值 */
};
struc rlimit不僅可以設定產生coredump檔案還可以設定很多系統資源:
RLIMIT_AS: 限制一個程序對映虛擬記憶體的大小。
RLIMIT_CORE:產生core dump檔案。
RLIMIT_FSIZE:一個程序可以開啟的檔案數量。
...
4、除錯過程
#include <sys/time.h>
#include <sys/resource.h>
#include<stdio.h>
#include <string.h>
#include<errno.h>
void fun_test(char *src, char *dst){
strncpy(dst, src, strlen(src));
}
int main(){
struct rlimit limit;
if(0 != getrlimit(RLIMIT_CORE, &limit)){
printf("%s", strerror(errno));
return 0;
}
limit.rlim_cur = RLIM_INFINITY; /*表示無窮大,不限制, 也可以指定core dump文大小*/
limit.rlim_max = RLIM_INFINITY;
if (0 == setrlimit(RLIMIT_CORE, &limit)){
printf( "setrlimit core dump success.\n");
}
char *pr = NULL;
char str[16] = {0};
fun_test(pr, str);
return 0;
}
編譯執行產生了coredump檔案core-setrlimit-18503-1543588372
除錯通過gdb ,除錯命令是gdb 程序名 coredump檔案,然後通過where命令檢視
通過gdb除錯我們知道程式掛在fun_test函式中的strlen函式,傳進去一個野指標。