使用MiniDumpWriteDump API 来生成程序的Dump

C++程序中dump文件生成方法详解 最近项目中新作成了一个动态链接库,长时间运行后,偶尔会崩溃。根据log分析,被调用的动态库函数最外层catch到了这个异常,但是不能定位哪里出了问题。另外虽然上层exe是有dump文件输出处理的,但是在C++中,如果异常被捕获并处理的情况下,系统就不会生成dump文件了。如果仍希望在try-catch块中捕获异常的同时生成dump文件,就必须在catch块中手动调用生成dump文件的函数。这样可以在异常被捕获后仍然生成dump文件以供后续分析。本文详细介绍下怎么生成dump文件。 阅读详情

MiniDumpWriteDump是MS DbgHelp.dll 中一个API, 用于导出当前运行的程序的Dump. 这个dll程序系统中就有, 但是很多软件, 都在自己的安装目录下保存了这个.dll的最新的版本.

为了测试这个API, 参考网上一些资料, 写了一个简单的C++ 程序. 目的是当有异常发生的时候, 自动生成Dump文件供之后的分析. 有了Dump文件, 我们就可以使用WinDBG等调试器来分析异常发生时的情况. 其实这个功能很多软件都有, 比如QQ, 魔兽世界, 等等. 它们在出现了异常的时候会弹出一个对话框, 让用户输入异常发生时的情况, 然后把异常的dump文件用email发回, 供开发者们分析修改bug.

不过有一点, 这里需要程序的调试符号文件(pdb文件). 对于Debug版来说, 是生成的, 但是Release版来说默认是不生成的. 可以设置VC的编译器, 让它在Release版的时候也生成调试信息. 这带来一个新的问题, 因为.pdb里面是保存了源文件的信息的, 为了避免泄密, 可以采用VS中的CVPack工具, 从中去除敏感的信息.

程序需要使用Dbghelp.h 和 Dbghelp.lib . 它们可以从MSDN找到.

//最主要的函数, 生成Dump
static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo)
{
if (excpInfo == NULL)
 //如果没有传入异常, 比如是在程序里面调用的, 生成一个异常
{
// Generate exception to get proper context in dump
__try 
{
OutputDebugString(_T("raising exception\r\n"));
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
} 
__except(DumpMiniDump(hFile, GetExceptionInformation()),
EXCEPTION_CONTINUE_EXECUTION) 
{
}
} 
else
{
OutputDebugString(_T("writing minidump\r\n"));
MINIDUMP_EXCEPTION_INFORMATION eInfo;
eInfo.ThreadId = GetCurrentThreadId(); 
//把需要的信息添进去
eInfo.ExceptionPointers = excpInfo;
eInfo.ClientPointers = FALSE;

    // 调用, 生成Dump. 98不支持
// Dump的类型是小型的, 节省空间. 可以参考MSDN生成更详细的Dump.
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
excpInfo ? &eInfo : NULL,
NULL,
NULL);
}
}

下面的是程序部分:

int _tmain(int argc, _TCHAR* argv[])
{
// 创建一个Dump文件
HANDLE hFile = CreateFile( _T("MiniDump.dmp"), GENERIC_READ | GENERIC_WRITE, 
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 
int code;
__try 
{   
// 把自己实现的main函数包装一下, 放在try .. except 块中. 这样出现了异常可以自动生成dump
main_wrapper(argc, argv); 
}
__except( code=GetExceptionCode(), DumpMiniDump(hFile, GetExceptionInformation() ),       EXCEPTION_EXECUTE_HANDLER ) 
//出现了异常, 记录异常的code, 生成dump!!
{
printf("%x\n", code);
wchar_t msg[512];
wsprintf(msg, L"Exception happened. Exception code is %x", code);
MessageBox(NULL, msg, L"Exception", MB_OK); 
//显示消息给用户
}
CloseHandle( hFile ); 
//关闭Dump文件
getchar();
return 0; 
}

最下面是两个测试的函数, main_wrapper函数将调用test1, test1将会生成一个异常(非法内存写)

void test1() {
int *p;
p = (int*)0x100; 
*p = 0; 
//写0x100地址, 这个是非法的
}

void main_wrapper(int argc, _TCHAR* argv[]) {
test1();
}

运行, 异常被捕获了:

clip_image001

同时, dump文件也生成了:

clip_image002

用WinDBG打开Dump文件, 可以清楚的看出异常出现的情况:

clip_image003


从中可以比较清楚的看到异常发生的情况(Exception code), 异常出现的地址(test1函数, 偏移0x28). 因为这次测试的是Debug版, 有保存了源代码的.pdb文件,所以WinDbg把源代码也列出来了. 这样可以非常容易的发现问题.

============================================

参考:
DbgHelp中的DumpAPI例子: http://www.debuginfo.com/examples/src/effminidumps/MiniDump.cpp 
CrashReport: 程序出现异常的时候显示发送错误的对话框, 并把Dump文件发送到指定的地址. http://code.google.com/p/crashrpt/
XCrashReport: 与上面的类似的一个开源项目. http://www.codeproject.com/KB/debug/XCrashReportPt1.aspx

程序在崩溃时记录出错的位置-Dump文件 Debug模式下,出异常时,很容易找到出错的位置和callstack信息。 但发布以后,再出异常的时候,就必须用到DUMP文件了。 本文主要是参考了http://blog.youkuaiyun.com/starlee/article/details/6630816  调用的API B 阅读详情

相关推荐

dump系列(2)C++程序异常或内存错误,导致闪退的解决办法:分析dump文件

如何在发布后程序中捕获程序的崩溃和异常往往是比较麻烦的事情,一般采用日志记录的方法来记录程序运行的每个流程,但是通常为了程序运行的性能,日志记录的方法只是记录程序运行的每个主要的处理流程,不能进行具体详细的记录,比如for 循环中的崩溃记录。C++语言中调用window API函数CreateFile()和MiniDumpWriteDump(),可以方便的记录程序崩溃时的Dump信息,并保持dum...

$firecat利白的代码足迹$ 4854

【小沐学C++】C++ 捕获程序异常奔溃minidump

并不是所有的bug都可以在发布前找到,也就是说并不是所有的抛出异常的bug都可以在发布前找到。幸运的是,微软在 Platform SDK 中包含了一个功能,可以帮助开发人员收集用户发现的异常信息。MiniDumpWriteDump函数将必要的故障转储信息写入文件,而不节省整个进程空间。此故障转储信息文件称为小型转储。这篇技术文章提供了有关如何编写和使用小型转储的信息。╮( ̄▽ ̄)╭如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???.........

爱看书的小沐 5828

如何让C++程序生成dump文件?生成dump文件的方式有哪些?如何使用Windbg分析dump文件?

本文详细介绍了如何让C++程序生成dump文件、生成dump文件的多种方式以及如何使用Windbg分析dump文件,并给出了对应的实战分析案例,有一定的实战参考价值。

dvlinker的技术专栏 5万+

VC++ MiniDumpWriteDump 保存程序的DUMP调试文件信息,类似于 Linux 下面的 core 调试信息文件。

WIN32K结构化异常筛选器函数实现:类似 catch when 的语法效果。

liulilittle的博客 604

如何让C++程序自动生成dump文件?如何使用Windbg分析dump文件?

本文讲述如何让C++程序自动生成dump文件,以及如何使用Windbg分析dump文件。

dvlinker的技术专栏 9611

【C++软件调试技术】dump文件类型与dump文件生成方法详解

dump文件类型与dump文件生成方法详解。

dvlinker的技术专栏 2万+

跨平台 C++ 程序崩溃调试与 Dump 文件分析

本篇博客将介绍如何在代码中自动生成Dump文件,并详细解析Dump相关参数,帮助开发者快速定位Bug。

Darker的博客 2450

Win10无外网热点搭建全指南:纯局域网通信与设备互联

热点并不是只有共享上网一种用途。在很多工程与办公场景中,我们需要的是让手机、笔记本、开发板等设备临时组成一个纯内网,完成文件传输、端口调试或局域网联机,而不需要任何外网出口。Win10笔记本在不连接互联网的状态下,借助系统移动热点或netsh承载网络,完全可以创建一个无外网热点,实现设备间二层互通。其核心在于利用SoftAP建立虚拟无线接入点,并绕开或禁用ICS的NAT转发。掌握这一技术,可在会议、出差、物联网调试等场景中快速搭建临时局域网,无需额外路由器。本文详细梳理三种实现路径、操作步骤及常见故障排查,

weixin_29230773的博客 238

MiniDumpWriteDump函数生成dmp文件

MiniDumpWriteDump函数生成dmp文件

cxd1314520的博客 1022

ESP-IDF 5.4下esp32-camera组件编译报错?手把手教你解决头文件缺失问题

本文详细解析了ESP-IDF 5.4环境下esp32-camera组件编译时出现的头文件缺失问题,提供了从目录结构优化、CMake配置到VSCode智能感知设置的完整解决方案。针对第三方组件集成难题,文章特别强调了PRIV_REQUIRES依赖声明和路径配置的关键作用,帮助开发者高效解决编译错误并建立稳定的开发环境。

weixin_28829629的博客 309

c++实现异步线程池并详细分析线程池析构流程

多线程编程是提高程序性能和响应能力的关键技术之一,异步线程池作为多线程编程的一种有效实现方式,能够管理和复用线程资源,避免频繁创建和销毁线程带来的开销。在本文中,我们将深入探讨如何实现一个异步线程池。

2301_76564925的博客 1598

使用MiniDumpWriteDump API 来生成程序的Dump(转载)

使用MiniDumpWriteDump API 来生成程序的Dump(转载) 2009-09-15 11:22 MiniDumpWriteDump是MS DbgHelp.dll 中一个API, 用于导出当前运行的程序的Dump. 这个dll程序系统中就有, 但是很多软件, 都在自己的安装目录下保存了这个.dll的最新的版本. 为了测试这个API, 参考网上一些资料,

xieshuting的专栏 1320

数据库常见面试题(附答案)

1.事务四大特性 原子性,要么执行,要么不执行 隔离性,所有操作全部执行完以前,其它会话不能看到过程 一致性,事务前后,数据总额一致 持久性,一旦事务提交,对数据的改变就是永久的 2.数据库隔离级别,每个级别会引发什么问题,mysql默认是哪个级别 脏读:事务B读取事务A还没有提交的数据 不可重复读:两次事务读的数据不一致 幻读:事务A修改了数据,事务B也修改了数据,这时在事务A看...

csdn问鼎 46万+

.Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter

dump文件相信有些朋友已经很熟悉了,dump文件的作用在于保存进程运行时的堆栈信息,方便日后排查软件故障,提升软件质量。关于dump分析工具windbg、adplus的文章更多了,如果您还不知道怎么使用请移步: 使用Windbg找出死锁,解决生产环境中运行的软件不响应请求的问题 ADPlus简介 这里接我的上篇文章:送专利啦~~ .Net高阶异常处理之TopLevelEH继续讲...

weixin_30760895的博客 104

【深度学习新浪潮】Score Matching(分数匹配):原理、推导与PyTorch实战

在概率模型训练中,配分函数(归一化常数)是绕不开的难题——尤其是能量模型(EBM)、扩散模型等未归一化模型,直接计算配分函数几乎不可能。Score Matching(分数匹配)作为一种无归一化的参数估计方法,通过拟合概率密度的对数梯度(分数函数),彻底避开了配分函数的计算,成为生成建模、密度估计的核心技术之一。本文将从基础概念出发,逐步推导Score Matching的核心公式,并结合PyTorch实现一个可直接运行的实战案例,帮你彻底理解这一关键技术。Score Matching的核心是。

专注:太空算力、AI infra、异构调度、大模型成本工程 250

深度强化学习 | 详解基于价值的强化学习DQN算法(附Pytorch实现)

深度Q网络DQN的核心原理是通过经验回放池和目标网络技术拟合高维状态空间,是Q-Learning算法的深度学习版本,本文分析DQN的基本算法,并给出训练实例和实际案例

FRIGIDWINTER的博客 4985

windows下qt程序意外崩溃,生成dump文件的方法

程序运行一段时间之后,意外退出,没有提示任何出错信息,这种情况可能是内存泄漏,但是没有提示错误信息,很难定位到具体代码。我们可以生成dump文件,定位出错位置。 在工程中添加代码: mdump.h #ifndef MDUMP1_H #define MDUMP1_H #include <Windows.h> #include <DbgHelp.h> // base...

二颖的博客 3674

基于ResNet + LLM大语言模型的分类识别系统设计与实现,Web前后端分离,Django+vue3+AI助手模块+ResNet50算法+LLM 联动+Element Plus等技术,全网独发

分类识别任务是计算机视觉中的重要任务,广泛应用于智慧校园分类、智慧农业、智慧生活场景分类等领域。常见的分类模型有 VGGNet、ResNet 、MobileNet 、ConvNeXt、DenseNet、ViT、Swin Transformer、YOLOv8/11/26。本项目结合 ResNet分类识别算法 + LLM大语言模型联动 ,使用 Django + Vue3,构建了一个通用的 Web 前后端系统,用户端 + 管理端 ,便于用户操作检,不仅可以用于大论文的工作量展示,还可以作为毕业设计。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 759
上一篇: 常用辅助函数集合
下一篇: IsKindOf()函数
且行且探索
博客等级 码龄14年 26粉丝 15原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值