內(nèi)容提要:
主要包含兩部分內(nèi)容:
1,core文件描述
2,core文件分析
說明:
一,Core 文件描述
Coredump 在unix 平臺是非常容易出現(xiàn)的一種錯誤形式,直接表現(xiàn)形式為core 文件, core 文件產(chǎn)生于當(dāng)前目錄下,
通常,象內(nèi)存地址錯誤、非法指令、總線錯誤等會引起coredump ,core 文件的內(nèi)容包含進程出現(xiàn)異常時的錯誤影
像。如果錯誤進程為多線程并且core 文件的大小受限于ulimit 的系統(tǒng)限制,則系統(tǒng)只將數(shù)據(jù)區(qū)中錯誤線程的堆棧區(qū)
復(fù)制到core 文件中。
應(yīng)當(dāng)注意,從AIX 5L 版本5.1 開始core 文件的命名格式可以通過環(huán)境變量CORE_NAMING 設(shè)置,其格式為:
core.pid.ddhhmmss ,分別代表為:
pid :進程標(biāo)示符
dd :當(dāng)前日期
hh :當(dāng)前小時
mm :當(dāng)前的分鐘
ss :當(dāng)前的秒
core 文件的缺省格式為老版本的格式,coredump 文件的內(nèi)容按照以下的順序組織:
1 ) core 文件的頭部信息
- 定義coredump 的基本信息,及其他信息的地址偏移量
- 定義loader 區(qū)的信息
- 定義核心線程的狀態(tài)信息,錯誤線程的mstsave 結(jié)構(gòu)信息直接存儲在core 文件的頭部區(qū),此區(qū)域只對多線程的
程序有效,除錯誤線程外的其他線程的mstsave 結(jié)構(gòu)信息存與此區(qū)域。
- 存儲coredump 時的用戶堆棧數(shù)據(jù)
- 存儲用戶數(shù)據(jù)區(qū)域信息
- 存儲匿名的內(nèi)存映射數(shù)據(jù)
- 存儲內(nèi)存映射區(qū)域的地址偏移量和大小信息
程堆棧、線程堆棧、線程mstsave 結(jié)構(gòu)、用戶結(jié)構(gòu)和錯誤時的寄存器信息,這些信息足夠跟蹤錯誤的產(chǎn)生。Core
文件的大小也可以通過setrlimit 函數(shù)設(shè)定。
二,Core 文件分析
首先分析coredump 的結(jié)構(gòu)組成,core 文件的頭信息是由結(jié)構(gòu)core_dump 結(jié)構(gòu)定義的,結(jié)構(gòu)成員定義如下:
成員 | 類型 | 描述 |
c_signo | char | 引起錯誤的信號量 |
C_entries | ushort | Coredump 的模塊數(shù) |
*c_tab | Struct ld_info | Core 數(shù)據(jù)的地址偏移量 |
成員 | 類型 | 描述 |
c_flag | char | 描述coredump 的類型,類型為: |
![]() |
![]() |
FULL_CORECore 包含數(shù)據(jù)區(qū)域 |
![]() |
![]() |
CORE_VERSION_1 生成 core 文件的AIX 的版本 |
![]() |
![]() |
MSTS_VALID 包含mstsave 的結(jié)構(gòu) |
![]() |
![]() |
CORE_BIGDATACore 文件包含大數(shù)據(jù) |
![]() |
![]() |
UBLOCK_VALIDCore 文件包含u_block 結(jié)構(gòu) |
![]() |
![]() |
USTACK_VALIDCore 文件包含用戶堆棧數(shù)據(jù) |
![]() |
![]() |
LE_VALIDCore 文件至少包含一個模塊 |
![]() |
![]() |
CORE_TRUNCCore 文件被截短 |
c_stack | Caddr_t | 用戶堆棧的起始地址偏移量 |
C_size | int | 用戶堆棧的大小 |
C_mst | Struct mstsave | 錯誤mst 的拷貝 |
C_u | Struct user | 用戶結(jié)構(gòu)的拷貝 |
C_nmsts | int | Mstsave 結(jié)構(gòu)的數(shù)量 |
C_msts | Struct mstsvae * | 線程的mstsave 結(jié)構(gòu)的地址偏移量 |
C_datasize | int | 數(shù)據(jù)區(qū)域的大小 |
C_data | Caddr_t | 用戶數(shù)據(jù)的地址偏移量 |
C_vmregions | int | 匿名地址映射的數(shù)量 |
C_vmm | Struct vm_info * | Vm_info 數(shù)據(jù)表的起始地址偏移量 |
借助于下面提供的程序可以分析core 文件的部分信息:
#include <stdio.h>
#include <sys/core.h>
void main(int argc, char *argv[])
{
FILE *corefile;
struct core_dumpx c_file;
char command[256];
if (argc != 2) {
fprintf(stderr, "Usage: %s <corefile>\n", *argv);
exit(1);
}
if ((corefile = fopen(argv[1], "r")) == NULL) {
perror(argv[1]);
exit(1);
}
fread(&c_file, sizeof(c_file), 1, corefile);
fclose(corefile);
sprintf(command, "lquerypv -h %s 6E0 64 | head -1 | awk '{print $6}'", argv[1]);
printf("Core created by: \n");
system(command);
printf("Signal number and cause of error number: %i\n", c_file.c_signo);
printf("Core file type: %i\n", c_file.c_flag);
printf("Number of core dump modules: %i\n", c_file.c_entries);
printf("Core file format number: %i\n", c_file.c_version);
printf("Thread identifier: %i\n", c_file.c_flt.th.ti_tid);
printf("Process identifier: %i\n", c_file.c_flt.th.ti_pid);
printf("Current effective priority: %i\n", c_file.c_flt.th.ti_pri);
printf("Processor Usage: %i\n", c_file.c_flt.th.ti_cpu);
printf("Processor bound to: cpu%i\n", c_file.c_flt.th.ti_cpuid);
/* if (c_file.c_flt.th.ti_cpu > 1) printf("Last Processor: cpu%i\n", c_file.c_flt.th.ti_affinity);
*/
exit(0);
}
假定以上程序的可執(zhí)行程序名稱為anacore ,按照以下步驟察看其運行結(jié)果:
1 ) 通過下面的程序生成core 文件
- main() {
char *testadd;
strcpy(testadd, 搣Just a testing攠);
}
程序命名為core.c
- xlc –o pcore core.c
4 ) 運行anacore 察看結(jié)果
- anacore core
Core created by:
|pcore...........|
Signal number and cause of error number: 11
Core file type: 114
Number of core dump modules: 0
Core file format number: 267312561
Thread identifier: 40827
Process identifier: 9520
Current effective priority: 60
Processor Usage: 0
Processor bound to: cpu-1
從上面的結(jié)果,我們可以簡單的分析產(chǎn)生core 文件的應(yīng)用、信號量及進程等信息,如果要求一
些更詳細(xì)的信息,可以借助于dbx 等調(diào)試工具進一步分析。