1.生成core檔案的設定
首先,linux下預設不生成core檔案。
使用
使用ulimit -c
指令可檢視core檔案的生成開關,如果為0則表示關閉此功能。
使用
ulimit -c filesize
指令,可以限制core檔案的大小(filesize的機關為kbyte)。
使用
ulimit -c unlimited
,則表示core檔案的大小不受限制。
有以下三種方法可以生成core檔案:
1.永久生成core問件。将
ulimit -c unlimited
寫進系統配置裡,即在
/etc/profile
裡面加上上述指令,這樣重新開機後生效了。或者使用source指令使之馬上生效。
source /etc/profile
2.隻在目前終端裡打開。cd到程式目錄,輸入
ulimit -c unlimited
,然後進行編譯,也可以生成生成core檔案。
3.在程式裡使用
setrlimit
函數設定生成core檔案。包含
#include<sys/resource.h>
,然後在程式裡加上如下代碼也可以生成core檔案。
struct rlimit limit;
limit.rlim_cur = RLIM_INFINITY;
limit.rlim_max = RLIM_INFINITY;
if(setrlimit(RLIMIT_CORE, &limit))
{
cout<<"set limit failed/n"<<endl;
}
2. Core檔案路徑設定
第一次通過setrlimit函數設定core檔案可生成後,程式崩潰後可執行檔案所在目錄并沒有core檔案,後來發現是我的core檔案生成路徑的問題,于是我在home/zh目錄下建立了一個coredump檔案夾,并使用如下指令設定它為core檔案生成目錄:
echo /home/zh/coredump/core.%e.%p> /proc/sys/kernel/core_pattern
生成的core檔案會放在
/home/zh/coredump
目錄,
core.%e.%p
是core檔案的命名,%e和%p是參數,含義如下:
參數 | 含義 |
---|---|
%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 添加指令名 |
3. 編譯連結程式,并執行可執行檔案
如圖3-1所示,程式有一個warning,執行後産生了段錯誤

4. 檢視core檔案
如圖4-1所示,cd到coredumo檔案下,使用ls檢視檔案,可以看到生成的core檔案,将可執行檔案拷到該路徑下,如圖4-2所示,便可以開始調試。
5. 開始調試
(1) 使用
gdb test core.test.3984
開始調試,如圖5-1所示,顯示testcore.cpp的11行出錯。
(2) 使用bt檢視堆棧資訊,如圖5-2所示,顯示了兩層堆棧資訊,因為在main函數中我隻調用了test函數,是以隻有它們的堆棧資訊。
(3) 使用where指令可以看到具體的出錯位置,如圖5-3所示。
(4) 使用f(n)指令切換堆棧的層數,如圖5-4所示,f(1)會顯示出第一層的堆棧資訊,即main函數,因為隻有2層,是以f(2)沒有資訊。
(5) 最後,可以列印出變量的值,如圖5-5所示,print p 指令會顯示p變量的資訊。
6.測試代碼
#include <iostream>
#include <stdio.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<unistd.h>
using namespace std;
void test()
{
char* p="zhanghan";
p[]='w';
cout<<*p<<endl;
}
int main()
{
struct rlimit limit;
limit.rlim_cur = RLIM_INFINITY;
limit.rlim_max = RLIM_INFINITY;
if(setrlimit(RLIMIT_CORE, &limit))
{
cout<<"set limit failed/n"<<endl;
}
test();
return ;
}