现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

让程序在崩溃时体面的退出(5):SEH+Dump文件

2013-08-20 06:59 工业·编程 ⁄ 共 1954字 ⁄ 字号 评论 1 条

    在上篇文章《让程序在崩溃时体面的退出(4):SEH》中讲解了SEH中try/except可以捕捉异常,避免程序的崩溃,并且可以在处理完异常之后,还能决定进该进程如何执行。对于应用程序的使用者来说,并不知道异常的发生。但是对于软件的开发者来说,虽然避免了程序的崩溃,可是这样可以让程序崩溃的缺陷存在于代码中,就像一个定时炸弹,不知道什么时候会爆炸。要想修复这样的缺陷,首先要找到导致程序崩溃的那行代码。而在那篇《让程序在崩溃时体面的退出(3):Dump文件》里面介绍了如何用Dump文件来定位使程序崩溃的代码。这里依然可以用同样的方法。下面就是创建Dump文件的函数。

// 创建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); 

       从上面的代码中可以看出,要想创建Dump文件,必须得到一个指向EXCEPTION_POINTERS结构的指针。怎么在try/except块中得到这个指针呢?这个时候就需要用到Windows API中的GetExceptionInformation()。这个函数的返回值就是一个指向EXCEPTION_POINTERS结构的指针。下面是具体的代码。

// 作为except块中表达式的函数 
// 
LONG CrashHandler(EXCEPTION_POINTERS *pException) 
{    
    // 在这里添加处理程序崩溃情况的代码 
    // 
 
    // 这里以弹出一个对话框为例子 
    // 
    MessageBox(NULL, _T("Message from Catch handler"), _T("Test"), MB_OK); 
 
    // 创建Dump文件 
    // 
    CreateDumpFile(_T("C:\\Test.dmp"), pException); 
 
    return EXCEPTION_EXECUTE_HANDLER; 

 
int _tmain(int argc, _TCHAR* argv[]) 

    __try 
    { 
        MessageBox(NULL, _T("Message from '__try' section"), _T("Test"), MB_OK); 
 
        // 除零,人为的使程序崩溃 
        // 
        int i = 13; 
        int j = 0; 
        int m = i / j; 
    } 
    // 捕捉到让程序崩溃的异常时创建Dump文件 
    // 
    __except(CrashHandler(GetExceptionInformation())) 
    { 
        // 这里以弹出一个对话框为例子 
        // 
        MessageBox(NULL, _T("Message from '__except' section"), _T("Test"), MB_OK); 
    } 
 
    MessageBox(NULL, _T("Funcation completed"), _T("Test"), MB_OK); 
 
    return 0; 

编译上面的代码并运行,会依次弹出下面这些对话框,并在C盘创建一个Dump文件Test.dmp。

        有了Dump文件,就可以轻松定位使程序崩溃的那行代码,具体方法可参考我的《让程序在崩溃时体面的退出(3):Dump文件》。

目前有 1 条留言    访客:0 条, 博主:0 条 ,引用: 1 条

    外部的引用: 1 条

    • 让程序在崩溃时体面的退出(6):终极解决方案(SEH+Dump+Unhandled Exception Filter) « 求索阁

    给我留言

    留言无头像?