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

  • 相关阅读:
    mysql 远程登陆不上
    hdu 5339 Untitled【搜索】
    SqlServer 书目
    passwordauthentication yes
    oracle 11g RAC ocfs2
    Oracle 11g RAC database on ASM, ACFS or OCFS2
    CentOS ips bonding
    Oracle 11g RAC features
    openStack 王者归来之 trivial matters
    openstack windows 2008 img
  • 原文地址:https://www.cnblogs.com/hanf/p/1625566.html
Copyright © 2011-2022 走看看