zoukankan      html  css  js  c++  java
  • 程序自动生成Dump文件

    前言:通过drwtsn32、NTSD、CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD、CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD、CDB等调试工具。了解了mini dump文件格式后,完全可以程序自动生成Dump文件。

    本文主要讨论以下内容:

    1、  运行原理

    2、  程序修改

    3、  注意事项

    一、   运行原理

    当程序遇到未处理异常(主要指非指针造成)导致程序崩溃死,如果在异常发生之前调用了SetUnhandledExceptionFilter()函数,异常交给函数处理。MSDN中描述为:

    Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.

    因而,在程序开始处增加SetUnhandledExceptionFilter()函数,并在函数中利用适当的方法生成Dump文件,即可实现需要的功能。

    二、   程序修改

    1、  重载 << 操作符。(本步可以不实现)

    std::ostream& operator<<(std::ostream& os, const EXCEPTION_RECORD& red)

    {

    return os << "   Thread ID:" << GetCurrentThreadId()

    << "   ExceptionCode: " << red.ExceptionCode << "/n"

    << "   ExceptionFlags: " << red.ExceptionFlags << "/n"

    << "   ExceptionAddress: " << red.ExceptionAddress << "/n"

    << "   NumberParameters: " << red.NumberParameters;

    }

             

    2、  实现UnhandledExceptionFilter

    #include "minidmp.h"

    LONG WINAPI GPTUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)

    {

    CreateMiniDump(pExceptionInfo, L"Exception.dmp");

                  std::cerr << "未知错误:" << (*pExceptionInfo->ExceptionRecord) << std::endl;

                  exit(pExceptionInfo->ExceptionRecord->ExceptionCode);

                 

                  return EXCEPTION_EXECUTE_HANDLER;    // 程序停止运行

    }

    3、  在异常发生之前调用SetUnhandledExceptionFilter(GPTUnhandledExceptionFilter);

    通常在Main()函数开始时调用即可。

    4、  CreateMiniDump()函数在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,

                                              constPMINIDUMP_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 : 0, 0, &mci);

     

           CloseHandle(hFile);

      }

    }

    三、   注意事项

    1、  可执行文件(exe)必须找到dbghelp.dll,才能生成Dump文件。这个DLL可以从调试工具包中找到。

    2、  当异常代码定位成功以后,如果无法阻止异常的产生,可以用 __try 结构包装异常代码,__try 和 try 不同,前者可以捕获非法指针产生的异常。

    __try {

    // 会异常的函数

    }

    __except( EXCEPTION_EXECUTE_HANDLER ){

    // 异常处理

    }

    参考文档:

    http://blog.csdn.net/ArCoolGG/archive/2007/04/05/1553027.aspx

    http://www.debuginfo.com/articles/effminidumps.html

    http://blog.csdn.net/jiangxinyu/article/details/5348770

  • 相关阅读:
    js中的原生Ajax和JQuery中的Ajax
    this的用法
    static的特性
    时政20180807
    java compiler没有1.8怎么办
    Description Resource Path Location Type Java compiler level does not match the version of the installed Java project facet Unknown Faceted Project Problem (Java Version Mismatch)
    分词器
    [数算]有一个工程甲、乙、丙单独做,分别要48天、72天、96天完成
    一点感想
    解析Excel文件 Apache POI框架使用
  • 原文地址:https://www.cnblogs.com/findumars/p/5650564.html
Copyright © 2011-2022 走看看