MFC程序自动生成dump Windbg文件

  在客户机器上如何得到应该程序的详细出错信息, 这里使用drwtsn32,在应用程序崩溃的时候自动将调用栈的信息以文件形式保存在磁盘。

  生成dump有drwtsn32, NTSD,CDB等多种工具,drwtsn32 于系统自带。

  在项目中使用以下几个步骤:

1. 创建minidmp.h  

minidmp.h
#pragma once
#include 
<windows.h>
#include 
<imagehlp.h>
#include 
<stdlib.h>
#pragma comment(lib, "dbghelp.lib")

inline BOOL IsDataSectionNeeded(
const WCHAR* pModuleName)
{
    
if(pModuleName == 0)
    {
        
return FALSE;
    }

    WCHAR szFileName[_MAX_FNAME] 
= L"";
    _wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);
    
if(wcsicmp(szFileName, L"ntdll"== 0)
        
return TRUE;
    
return FALSE; 
}

inline BOOL CALLBACK MiniDumpCallback(PVOID                            pParam, 
                                      
const PMINIDUMP_CALLBACK_INPUT   pInput, 
                                      PMINIDUMP_CALLBACK_OUTPUT        pOutput)
{
    
if(pInput == 0 || pOutput == 0)
        
return FALSE;

    
switch(pInput->CallbackType)
    {
    
case ModuleCallback: 
        
if(pOutput->ModuleWriteFlags & ModuleWriteDataSeg) 
            
if(!IsDataSectionNeeded(pInput->Module.FullPath)) 
                pOutput
->ModuleWriteFlags &= (~ModuleWriteDataSeg); 
    
case IncludeModuleCallback:
    
case IncludeThreadCallback:
    
case ThreadCallback:
    
case ThreadExCallback:
        
return TRUE;
    
default:;
    }
    
return FALSE;
}

inline 
void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName)
{
    HANDLE hFile 
= CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE,
        
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    
if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
    {
        MINIDUMP_EXCEPTION_INFORMATION mdei;
        mdei.ThreadId           
= GetCurrentThreadId();
        mdei.ExceptionPointers  
= pep;
        mdei.ClientPointers     
= FALSE;
        MINIDUMP_CALLBACK_INFORMATION mci;
        mci.CallbackRoutine     
= (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
        mci.CallbackParam       
= 0;
        MINIDUMP_TYPE mdt       
= (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory | 
            MiniDumpWithDataSegs 
| 
            MiniDumpWithHandleData 
|
            
0x00000800 /*MiniDumpWithFullMemoryInfo*/ | 
            
0x00001000 /*MiniDumpWithThreadInfo*/ | 
            MiniDumpWithUnloadedModules);
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
            hFile, mdt, (pep 
!= 0? &mdei : 00&mci);
        CloseHandle(hFile); 
    }
}

 

2、  实现UnhandledExceptionFilter

 

GPTUnhandledExceptionFilter
#include "minidmp.h"

LONG WINAPI GPTUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
    
//得到当前时间
    SYSTEMTIME st;
    ::GetLocalTime(
&st);
    
//得到程序所在文件夹
    TCHAR exeFullPath[256]; // MAX_PATH
    GetModuleFileName(NULL,exeFullPath,256);//得到程序模块名称,全路径 
    CString strPath;
    DWORD nLoc;
    strPath.Format(
"%s",exeFullPath);  
    nLoc 
= strPath.ReverseFind('\\');
    strPath.Delete(nLoc
+1,strPath.GetLength()-nLoc); 

    LPSTR szFileName;
    wsprintf(szFileName, TEXT(
"%sERLOG_%04d%02d%02d%02d%02d%02d%02d%02d.dmp"),strPath, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, rand()%100);
    CreateMiniDump(pExceptionInfo, szFileName);
    std::cerr 
<< "未知错误:" << (*pExceptionInfo->ExceptionRecord) << std::endl;
    exit(pExceptionInfo
->ExceptionRecord->ExceptionCode);
    
return EXCEPTION_EXECUTE_HANDLER;    // 程序停止运行
}

 

3.  在异常发生之前调用SetUnhandledExceptionFilter(GPTUnhandledExceptionFilter); 通常在Main()函数开始时调用即可。

 

 

注:必需有dbghlp.dll

posted @ 2009-12-16 14:30  Hanf  阅读(3360)  评论(0编辑  收藏  举报
Copyright © 2008-2016 Hanf All Rights Reserved