当前位置: 首页 > news >正文

程序自动生成Dump文件

前言:通过drwtsn32NTSDCDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSDCDB可以完全解决,但并不是所有的操作系统中都安装了NTSDCDB等调试工具。了解了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::ostreamoperator<<(std::ostreamosconst EXCEPTION_RECORDred)

{

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(pExceptionInfoL"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 WCHARpModuleName)

{

  if(pModuleName == 0)

  {

       return FALSE;

  }

 

  WCHAR szFileName[_MAX_FNAME] = L"";

  _wsplitpath(pModuleNameNULLNULLszFileNameNULL);

 

  if(wcsicmp(szFileNameL"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_POINTERSpepLPCTSTR strFileName)

{

  HANDLE hFile = CreateFile(strFileNameGENERIC_READ | GENERIC_WRITE,

       0, NULLCREATE_ALWAYSFILE_ATTRIBUTE_NORMALNULL);

 

  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(),

            hFilemdt, (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

相关文章:

  • Python:urllib 和urllib2之间的区别
  • 华为实习日记——第十二天
  • Js 读写cookies
  • ExpandableListView(可展开的列表组件)的说明以及其用法
  • 搭建mcollective高可用,使puppet架构更加安全、稳定
  • MyEclipse中add jars和add external jars的区别带来的svn checkout的问题
  • JS实现网页换肤功能效果
  • android firmware 利用UDP socket发送Magic Packet--c语言版本
  • angular controller as syntax vs scope
  • 并发编程实战的阅读(锁的重入)
  • 关于Java数据类型与底层内存运行机制
  • 关于MarshalByRefObject的解释
  • 吐槽一下12306的SQL注入漏洞
  • Java实现可乐瓶问题
  • [HTML]HTML5实现可编辑表格
  • @angular/forms 源码解析之双向绑定
  • 2017-09-12 前端日报
  • github指令
  • nginx 负载服务器优化
  • Python学习笔记 字符串拼接
  • Rancher如何对接Ceph-RBD块存储
  • react-native 安卓真机环境搭建
  • React-Native - 收藏集 - 掘金
  • Twitter赢在开放,三年创造奇迹
  • vue-cli在webpack的配置文件探究
  • 阿里研究院入选中国企业智库系统影响力榜
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 后端_MYSQL
  • 记一次删除Git记录中的大文件的过程
  • 简析gRPC client 连接管理
  • 京东美团研发面经
  • 跳前端坑前,先看看这个!!
  • 译有关态射的一切
  • 06-01 点餐小程序前台界面搭建
  • 白色的风信子
  • C# - 为值类型重定义相等性
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • # .NET Framework中使用命名管道进行进程间通信
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • ###STL(标准模板库)
  • (23)Linux的软硬连接
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (day6) 319. 灯泡开关
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (万字长文)Spring的核心知识尽揽其中
  • (一)SpringBoot3---尚硅谷总结
  • (转)关于多人操作数据的处理策略
  • .Net Core与存储过程(一)
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .sh 的运行
  • ??myeclipse+tomcat
  • @RequestMapping 的作用是什么?
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证