zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    oracle手工生成AWR报告方法
    oracle init.ora常用配置详解
    Statspack的使用
    控制用户的访问之权限、角色【weber出品必属精品】
    初识数据字典【weber出品必属精品】
    EMCA常用命令 【weber整理必出精品】
    全世界最详细的图形化VMware中linux环境下oracle安装(三)【weber出品必属精品】
    vi 快捷键【转】【weber整理必出精品】
    数据库对象(视图,序列,索引,同义词)【weber出品必属精品】
    解决linux下oracle进入sqlplus环境中后退键显示^H、上下键无效与ctrl+l无法清屏等问题【weber出品必属精品】
  • 原文地址:https://www.cnblogs.com/hanf/p/1625566.html
Copyright © 2011-2022 走看看