当程序崩溃 时 产生 崩溃转储文件 (dump)

一、前言

1. 什么是 core dump

  Coredump叫做核心转储,它是进程运行时在突然崩溃的那一刻的一个内存快照。操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个文件里。

   该文件也是二进制文件,可以使用gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb进行打开分析里面的具体内容。

   注:core是在半导体作为内存材料前的线圈,当时用线圈当做内存材料,线圈叫做core。用线圈做的内存叫做core memory。
 

2. 无法生成 dmp 文件

虽然我们知道进程在coredump的时候会产生core文件,但是有时候却发现进程虽然core了,但是我们却找不到core文件

可以将 dmp 文件的大小调高

 

二、创建 dmp 方法

1. 修改注册表 当程序崩溃时 产生崩溃转储文件(dmp)

以管理员身份 运行 :OpenDump.bat 其本质是写注册表。
运行后: 任何程序崩溃都会在C:\CrashDump 产生dmp文件(比较大,约50到200M)。
至少在Win7、Win10的电脑,Win10的平板上运行正确。

a) OpenDump.bat - 自动生成dmp文件

@echo off
echo 正在启用Dump...
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDump" /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f
echo Dump已经启用
pause
@echo on

b) 注册表 参数说明:

Value 描述 Type 默认值
DumpFolder 文件保存路径

REG_EXPAND_SZ

%LOCALAPPDATA%CrashDumps
DumpCount

dump文件的最大数目

REG_DWORD 10 【注 超过最大值时,将最早的 dmp 文件删除】
DumpType

指定生成的dump类型:
0:Custom dump
1:Mini dump
2:Full dump

REG_DWORD 1
CustomDumpFlags

仅在DumpType为0时使用
为MINIDUMP_TYPE的组合

REG_DWORD MiniDumpWithDataSegs | MiniDumpWithUnloadedModules |
MiniDumpWithProcessThreadData

c) CloseDump.bat - 关闭此功能

@echo off
echo 正在关闭Dump...
reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /f
echo Dump已经关闭
pause
@echo on

 2. 在程序中加入代码

程序中加入存储Dump的代码

通过SetUnhandledExceptionFilter设置捕获dump的入口,然后通过MiniDumpWriteDump生成dump文件

#include
#include
#pragma comment(lib,"DbgHelp.lib")
// 创建Dump文件
void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
{
	HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	// Dump信息
	MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
	dumpInfo.ExceptionPointers = pException;
	dumpInfo.ThreadId = GetCurrentThreadId();
	dumpInfo.ClientPointers = TRUE;
	// 写入Dump文件内容
	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
	CloseHandle(hDumpFile);
}
// 处理Unhandled Exception的回调函数
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
{	
	CreateDumpFile(L"Test.dmp",pException);
	return EXCEPTION_EXECUTE_HANDLER;
}
 
void fun(int *p)
{
	p[0]=0;
}
int main(int argc, char * argv[])
{
	//注册异常处理函数
	SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler); 
	fun(NULL);
	return 0;
 
}

 

3. 任务管理器 - 适用崩溃未立即退出

在程序崩溃后,先不关闭程序,在任务管理器中找到该程序对应的进程。右键—>创建转储文件

当程序崩溃 时 产生 崩溃转储文件 (dump)_第1张图片

此时会在默认的目录下创建出一个dump文件。

当程序崩溃 时 产生 崩溃转储文件 (dump)_第2张图片

可以看出,此种方法只适用于程序崩溃但没有立即自行退出的情况。倘若程序故障后自行退出,则此方法就难以应用。

4. WinDbg抓取 - 适用崩溃未立即退出

程序运行崩溃后,先不关闭程序,将WinDbg附加到改进程上

当程序崩溃 时 产生 崩溃转储文件 (dump)_第3张图片

执行命令:.dump –ma Test.dmp  ,则会产生一个Test.dmp的转储文件。

当程序崩溃 时 产生 崩溃转储文件 (dump)_第4张图片

三、调试

1. 注意事项

      a) 最好把 exe, pdb, dmp 放到同一文件夹下

      b) 必须保证pdb与出问题的exe是同一时间生成的

      c) 当把 pdb 文件与 dmp 文件放入同一目录下时,就不需设置其路径,否则需要设置 符号表 文件路径 和 源代码路径

工具->选项->调试->符号:

当程序崩溃 时 产生 崩溃转储文件 (dump)_第5张图片

设置源代码路径: 属性->调试源代码

当程序崩溃 时 产生 崩溃转储文件 (dump)_第6张图片

 

 

 

你可能感兴趣的:(C/C++)