让程序在崩溃时体面的退出之Dump文件

本文介绍了如何在程序崩溃时利用MiniDumpWriteDump函数创建Dump文件,以及如何在Visual Studio中打开和调试Dump文件,帮助开发者定位和解决程序错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在我的那篇《 让程序在崩溃时体面的退出之CallStack》中提供了一个在程序崩溃时得到CallStack的方法。可是要想得到CallStack,必须有pdb文件的支持。但是一般情况下,发布出去的程序都是Release版本的,都不会附带pdb文件。那么我们怎么能在程序崩溃的时候找到出错的具体位置呢?这个时候就该Dump文件出场了!Dump文件是进程的内存镜像,可以把程序运行时的状态完整的保存下来。
        要想在程序崩溃的时候创建Dump文件,就需要用到DbgHelp.dll中Windows API的MiniDumpWriteDump()函数。该函数声明如下:
  1. BOOL WINAPI MiniDumpWriteDump( 
  2.   __in  HANDLE hProcess, 
  3.   __in  DWORD ProcessId, 
  4.   __in  HANDLE hFile, 
  5.   __in  MINIDUMP_TYPE DumpType, 
  6.   __in  PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
  7.   __in  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 
  8.   __in  PMINIDUMP_CALLBACK_INFORMATION CallbackParam 
  9. ); 
BOOL WINAPI MiniDumpWriteDump(
  __in  HANDLE hProcess,
  __in  DWORD ProcessId,
  __in  HANDLE hFile,
  __in  MINIDUMP_TYPE DumpType,
  __in  PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
  __in  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
  __in  PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);

        具体的参数和返回值的解释可以查找MSDN,有很详细的说明。下面依然用上一篇文章中的例子代码来说明怎么在程序崩溃的时候创建Dump文件。

  1. // 处理Unhandled Exception的回调函数 
  2. // 
  3. LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException) 
  4. {    
  5.     // 这里弹出一个错误对话框并退出程序 
  6.     // 
  7.     FatalAppExit(-1,  _T("*** Unhandled Exception! ***")); 
  8.  
  9.     return EXCEPTION_EXECUTE_HANDLER; 
  10.  
  11. // 一个有函数调用的类 
  12. //  
  13. class CrashTest 
  14. public
  15.     void Test()  
  16.     {  
  17.         Crash();  
  18.     } 
  19.  
  20. private
  21.     void Crash()  
  22.     {  
  23.         // 除零,人为的使程序崩溃 
  24.         // 
  25.         int i = 13; 
  26.         int j = 0; 
  27.         int m = i / j; 
  28.     } 
  29. }; 
  30.  
  31. int _tmain(int argc, _TCHAR* argv[]) 
  32.     // 设置处理Unhandled Exception的回调函数 
  33.     //  
  34.     SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);  
  35.  
  36.     CrashTest test; 
  37.     test.Test(); 
  38.  
  39.     return 0; 
// 处理Unhandled Exception的回调函数
//
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
{	
	// 这里弹出一个错误对话框并退出程序
	//
	FatalAppExit(-1,  _T("*** Unhandled Exception! ***"));

	return EXCEPTION_EXECUTE_HANDLER;
}

// 一个有函数调用的类
// 
class CrashTest
{
public:
	void Test() 
	{ 
		Crash(); 
	}

private:
	void Crash() 
	{ 
		// 除零,人为的使程序崩溃
		//
		int i = 13;
		int j = 0;
		int m = i / j;
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	// 设置处理Unhandled Exception的回调函数
	// 
	SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler); 

	CrashTest test;
	test.Test();

	return 0;
}

        在上面的程序崩溃的时候,会调用函数ApplicationCrashHandler()。创建Dump文件的代码就需要添加到该函数中。下面就是一个创建Dump文件的函数。

  1. // 创建Dump文件 
  2. //  
  3. void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException) 
  4.     // 创建Dump文件 
  5.     // 
  6.     HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
  7.  
  8.     // Dump信息 
  9.     // 
  10.     MINIDUMP_EXCEPTION_INFORMATION dumpInfo; 
  11.     dumpInfo.ExceptionPointers = pException; 
  12.     dumpInfo.ThreadId = GetCurrentThreadId(); 
  13.     dumpInfo.ClientPointers = TRUE; 
  14.  
  15.     // 写入Dump文件内容 
  16.     // 
  17.     MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL); 
  18.  
  19.     CloseHandle(hDumpFile); 
// 创建Dump文件
// 
void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
{
	// 创建Dump文件
	//
	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);
}

        在函数ApplicationCrashHandler()用类似下面的代码来调用上面的函数,就可以在程序崩溃的时候创建Dump文件。

  1. CreateDumpFile(_T("C:\\Test.dmp"), pException); 
CreateDumpFile(_T("C:\\Test.dmp"), pException);

        下面简单说一下Dump文件的用法。将Dump文件拷贝到含有应用程序和对应的pdb文件的目录,在VS里面打开Dump文件(或者直接双击Dump文件),VS会自动创建一个Solution,直接调试运行,代码就会停到使程序崩溃的那一行上。就跟在VS里面调试代码一摸一样。(VS2008)


        在VS2010里打开Dump文件,会显示一个Minidump File Summary,并且可以进行下面图中的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值