1. 程式人生 > >linux 下除錯coredump檔案

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

產生coredump檔案

除錯通過gdb ,除錯命令是gdb  程序名 coredump檔案,然後通過where命令檢視

gdb除錯core dump檔案

通過gdb除錯我們知道程式掛在fun_test函式中的strlen函式,傳進去一個野指標。