生成程序崩溃的dump文件,使用windbg调试

本文介绍了一种在Windows程序崩溃时自动生成DMP文件的方法,这种方法能够帮助开发者快速定位问题所在。通过设置异常处理回调函数并在其中调用MiniDumpWriteDump API,可以将崩溃时的内存状态保存为DMP文件,便于后续使用Windbg等工具进行分析。

1,目的


有时候程序在客户那里崩溃了,你程序也没有什么有效的log日志能记录到崩溃的细节,那这实在是一件很麻烦的事情。

你得向客户反复了解操作内容并希望能在自己这里重现,这个过程想想都很痛苦吧。。

使用下面的方法,能在程序崩溃时生成一个自己的dump文件,记录了崩溃时的一些有用的信息,一般能帮你容易地找到出错的地方。


2,原理


简单地说,就是windows程序崩溃时会调一个对话框显示一些没什么用的信息。

XP下:

WIN7中:

①设置崩溃时的回调函数。

有一个方法可以让我们设置程序崩溃时先执行的回调函数,这里面可以弹我们自己的对话框,比如让用户输入一些有用的内容然后发送给我们。

这个函数是SetUnhandledExceptionFilter . 

原型:

    WINBASEAPI  
    LPTOP_LEVEL_EXCEPTION_FILTER  
    WINAPI  
    SetUnhandledExceptionFilter(  
        __in_opt LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter  
        );  

它的参数是你要设置的回调函数:PTOP_LEVEL_EXCEPTION_FILTER
typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(  
    __in struct _EXCEPTION_POINTERS *ExceptionInfo  
    );  
typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; 



系统调起你的回调函数时,会给你传一个代表异常信息的结构:EXCEPTION_POINTERS

    typedef struct _EXCEPTION_POINTERS {  
        PEXCEPTION_RECORD ExceptionRecord;  
        PCONTEXT ContextRecord;  
    } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;  


我们现在要做的就是在回调函数里根据这个系统给我们的信息,记录到一个dump文件中去。供我们使用windbg分析。

通过SetUnhandledExceptionFilter 函数的返回值我们可以选择在回调结束后不再弹原来默认的对话框而直接结束程序、或者再弹那个默认的再结束程序、不弹对话框继续执行。

如下:

    #define EXCEPTION_EXECUTE_HANDLER       1           //在回调结束后不再弹原来默认的对话框而直接结束程序  
    #define EXCEPTION_CONTINUE_SEARCH       0       //再弹那个默认的再结束程序  
    #define EXCEPTION_CONTINUE_EXECUTION    -1      //继续执行  




②在回调函数中输出崩溃信息到dump文件。


往dump文件写内容用到一个API:MiniDumpWriteDump。

在DbgHelp.h头文件中,且需包含 DbgHelp.lib库。

    #include <DbgHelp.h>  
    #pragma comment(lib, "dbghelp.lib")  


函数形式:

    BOOL  
    WINAPI  
    MiniDumpWriteDump(  
        __in HANDLE hProcess,  
        __in DWORD ProcessId,  
        __in HANDLE hFile,  
        __in MINIDUMP_TYPE DumpType,  
        __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,  
        __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,  
        __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam  
        );  

说明:

hProcess  ——进程句柄,使用GetCurrentProcess()获得即可。
ProcessID——进程ID,GetCurrentProcessId()。

hFile          ——我们创建的dump文件句柄。

DumpType——dump类型,一般填MiniDumpNormal 即可,具体内容参看DbgHelp.h和MSDN。

ExceptionParam——  1)ThreadId:GetCurrentThreadId()。

2)ExceptionPointers:即回调函数的参数。

3)ClientPointers:一般填TRUE即可。

UserStreamParam—— 一般设NULL。

CallbackParam      —— 一般设NULL。


3,演示程序代码


如果是release版,需要在工程配置中设置生成调试文件和生成映射文件。

如图:



win32控制台程序:

    #include "stdafx.h"  
    #include <windows.h>  
    #include <DbgHelp.h>  
    #pragma comment(lib, "dbghelp.lib")  
      
    //我们的回调函数  
    LONG __stdcall ExceptCallBack( EXCEPTION_POINTERS *pExcPointer)  
    {  
        MessageBox(NULL,"程序崩溃!相关信息记录在C:\\Test.dmp文件中。",NULL,MB_OK);  
      
        //创建dump文件  
        HANDLE hFile = CreateFile("C:\\Test.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL ,NULL);  
          
        //向文件写下当前程序崩溃相关信息  
        MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;  
        loExceptionInfo.ExceptionPointers = pExcPointer;  
        loExceptionInfo.ThreadId = GetCurrentThreadId();  
        loExceptionInfo.ClientPointers = TRUE;  
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL);  
        CloseHandle(hFile);  
      
        return EXCEPTION_EXECUTE_HANDLER;  
    }  
      
    void WrongFun()  
    {  
        //crash  
        int * p = NULL;  
        *p = 1;  
    }  
      
    int _tmain(int argc, _TCHAR* argv[])  
    {  
        //设置崩溃回调函数  
        SetUnhandledExceptionFilter(ExceptCallBack);  
      
        WrongFun();  
      
        return 0;  
    }  


4,效果。

crash后先弹出一个对话框:


之后不再调windows自带的崩溃对话框了。程序结束。


5,使用windbg查看dmp文件


用windbg 菜单 File->Open Crash File 打开这个Test.dmp文件,在下方编辑框输入 “!analyze -v” 命令执行自动分析。

稍等一会,就会出现一些内容,大致找到如下:

就能看到程序崩溃的一些细节甚至代码。


原文地址:http://blog.youkuaiyun.com/dpsying/article/details/21453679
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值