MiniDump不生成或者生成0字节

news/2024/11/24 11:23:56/

今天在使用C写一个Windows多线程程序时,发现退出过程中有段错误,为了方便快速的定位问题,我使用了MiniDump。

MiniDump.c源码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <dbghelp.h>#pragma comment(lib, "dbghelp.lib")static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{BOOL bDumpOK = FALSE;wchar_t strDumpFileName[8192];size_t len = 0;wchar_t szPath[MAX_PATH];if (GetModuleFileNameW(NULL, szPath, sizeof(szPath))){time_t now = time(NULL);struct tm *_t = localtime(&now);len = swprintf(strDumpFileName, MAX_PATH, L"%ls.%4d%02d%02d_%02d%02d%02d.dmp", szPath,_t->tm_year + 1900, _t->tm_mon + 1, _t->tm_mday, _t->tm_hour, _t->tm_min, _t->tm_sec);HANDLE hFile = CreateFileW(strDumpFileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);if (hFile != INVALID_HANDLE_VALUE){MINIDUMP_EXCEPTION_INFORMATION exception_information;exception_information.ThreadId = GetCurrentThreadId();exception_information.ExceptionPointers = ExceptionInfo;exception_information.ClientPointers = TRUE;if (MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &exception_information, NULL, NULL))bDumpOK = TRUE;CloseHandle(hFile);}}if (bDumpOK){wchar_t *str = L"宕机了,MiniDump文件已经生成到:";size_t num = wcslen(str);memmove(&strDumpFileName[num], strDumpFileName, len * sizeof(wchar_t));memcpy(strDumpFileName, str, num * sizeof(wchar_t));MessageBoxW(NULL, strDumpFileName, L"提示", MB_OK);}else{MessageBoxW(NULL, L"宕机了,生成MiniDump文件失败。", L"提示", MB_OK);}return EXCEPTION_EXECUTE_HANDLER;
}void InitMiniDump()
{SetUnhandledExceptionFilter(ExceptionFilter);
}

但是测试了多次,要么是不能生成dump文件,要么生成的dump文件为0字节,之前在项目中使用C++时,专门做了一个CrashDumper的类,实际使用中是能够正常生成的:

MiniDump.h源码:

#ifndef _MINI_DUMPER_H_
#define _MINI_DUMPER_H_
#ifdef _MSC_VER#include <windows.h>#pragma comment(linker, "/include:?dumper@@3VCrashDumper@@A")class CrashDumper
{
public:CrashDumper();~CrashDumper();
};#endif
#endif

MiniDump.cpp源码:

#ifdef _MSC_VER
#pragma warning(disable:4091)
#include <windows.h>
#include <tchar.h>
#include <dbghelp.h>
#include <string>
#include "MiniDump.h"#pragma comment(lib, "dbghelp.lib")static LPTOP_LEVEL_EXCEPTION_FILTER m_OriginalFilter;
static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{BOOL bDumpOK = FALSE;wchar_t strDumpFileName[8192];size_t len = 0;wchar_t szPath[MAX_PATH];if (GetModuleFileNameW(NULL, szPath, sizeof(szPath))){time_t now = time(NULL);struct tm *_t = localtime(&now);len = swprintf(strDumpFileName, MAX_PATH, L"%ls.%4d%02d%02d_%02d%02d%02d.dmp", szPath,_t->tm_year + 1900, _t->tm_mon + 1, _t->tm_mday, _t->tm_hour, _t->tm_min, _t->tm_sec);HANDLE hFile = CreateFileW(strDumpFileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);if (hFile != INVALID_HANDLE_VALUE){MINIDUMP_EXCEPTION_INFORMATION exception_information;exception_information.ThreadId = GetCurrentThreadId();exception_information.ExceptionPointers = ExceptionInfo;exception_information.ClientPointers = TRUE;if (MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &exception_information, NULL, NULL))bDumpOK = TRUE;CloseHandle(hFile);}}if (bDumpOK){wchar_t *str = L"宕机了,MiniDump文件已经生成到:";size_t num = wcslen(str);memmove(&strDumpFileName[num], strDumpFileName, len * sizeof(wchar_t));memcpy(strDumpFileName, str, num * sizeof(wchar_t));MessageBoxW(NULL, strDumpFileName, L"提示", MB_OK);}else{MessageBoxW(NULL, L"宕机了,生成MiniDump文件失败。", L"提示", MB_OK);}return EXCEPTION_EXECUTE_HANDLER;
}CrashDumper dumper;
CrashDumper::CrashDumper()
{m_OriginalFilter = SetUnhandledExceptionFilter(ExceptionFilter);
}CrashDumper::~CrashDumper()
{SetUnhandledExceptionFilter(m_OriginalFilter);
}
#endif

实际使用中只需要包含CrashDumper的头文件即可,VC++的编译器会自动链接。

今天的MiniDump却不能正常工作,在ExceptionFilter函数中打日志,时而有输出,时而没输出,有输出都是在函数开头的日志有输出,后面的就没输出了。网上查询了一些资料:

SetUnhandledExceptionFilter无法捕获异常原因及解决方法
SetUnhandledExceptionFilter拦不住的崩溃
SetUnhandledExceptionFilter 的讨论
为什么SetUnhandledExceptionFilter不能捕获某些异常,而AddVectoredExceptionHandler可以捕获

使用了这些方面,发现还是不行,最后在主线程main函数返回前加了一句:

Sleep(1000);

即休眠一段时间,就生成了MiniDump了。

通过分析发现是另一个线程在退出时出现了宕机,但是主线程退出时还没来得及调用或者未完全调用完生成MiniDump文件,整个进程就结束了。简单粗暴的方法就是主函数退出前休眠一段时间,让异常处理程序有充分的时间生成MiniDump。


http://www.ppmy.cn/news/574805.html

相关文章

MiniDump文件的生成(一)

使用DbgHelp提供的MiniDumpWriteDump函数可以在程序崩溃的时候产生包含足够多信息的MiniDump文件供调试程序使用。 1. MiniDumpWriteDump的声明如下 详见: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680360(vvs.85).aspx 2. 作为示例&#xff0c;下面…

用windbg分析蓝屏文件minidump随记!!

用windbg分析蓝屏文件minidump&#xff0c;以解决加载驱动蓝屏的相关问题随记。 案例1&#xff1a;能够正常进入操作系统&#xff0c;按照如下提示设置: a. 右击“我的电脑”选择“属性”; b. 在弹出的对话框中选择 “高级”&#xff0d;> “设置”; c.“自动重新启动…

MINIDUMP_TYPE详解

MINIDUMP_TYPE 枚举类型详解 一、MINIDUMP_TYPE 的作用 相信大家都知道我们可以使用minidump文件来记录Windows程序崩溃时的信息&#xff0c;其是一种内存转储&#xff0c;其第一代原型是一种“全用户转储&#xff08;Full User Dump&#xff09;”,里面包含了全部的进程内存信…

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

文章目录 1、简介1.1 MiniDumpWriteDump函数1.2 Visual Studio分析小型转储1.3 使用 Microsoft 公共符号服务器1.4 使用 WinDbg 调试小型转储 2、代码实现2.1 例子一2.2 例子二2.3 例子三2.4 例子四2.5 其他例子 3、调试工具3.1 windbg3.2 debugdiag3.3 Visual Studio 结语 1、…

Minidump方式保留程序崩溃现场

介绍部分转自https://www.cnblogs.com/lisuyun/p/5245609.html 程序部分为原创。 Minidump方式保留程序崩溃现场 在Windows平台下用C开发应用程序&#xff0c;最不想见到的情况恐怕就是程序崩溃&#xff0c;而要想解决引起问题的bug&#xff0c;最困难的应该就是调试release版…

MiniDump文件的生成(二)

在《MiniDump文件生成&#xff08;一&#xff09;》中简单的介绍了一下怎样在程序崩溃的时候生成供调试使用的DMP文件&#xff0c;本文将详细的介绍一下MINIDUMP_TYPE中的每一种类型以及针对每一种类型所生成的DMP文件中将包含哪些特定信息。 首先来看一下&#xff0c;Windows…

写入的dump文件为0kb (1、MiniDumpWriteDump 简单理解)

1、了解下MiniDumpWriteDump MiniDumpWriteDump (vs2008) MSDN ImageHlp.h 文件 // …… 4647-4657BOOL WINAPI MiniDumpWriteDump(IN HANDLE hProcess,IN DWORD ProcessId,IN HANDLE hFile,IN MINIDUMP_TYPE DumpType,IN CONST PMINIDUMP_EXCEPTION_INFORMATION Excepti…

处理minidump文件用到的“工具”的分享

前言 最近崩溃平台有BUG&#xff0c;native的崩溃堆栈解析不出来&#xff0c;只能自己线下人肉解堆栈了。本着能善用工具提高工作效果的习惯&#xff0c;最终收获了如下的zshe脚本&#xff08;方法&#xff09;用于后续的工作&#xff0c;借此笔记跟大家分享与交流&#xff0c…