DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

使用代码手工生成dmp文件

  • SetUnhandledExceptionFilter

为每个线程设置SetUnhandledExceptionFilter(MyCallBack),(必须在每个线程中启动时调用一次,否则造成无法进入回调函数中)这样该线程中发现未处理的 SEH 异常时就会进入到MyCallBack 回调中.

无聊的是虽然MyCallBack 的参数是 SEH 异常的结构体指针,但 C++ 异常也会进入到MyCallBack 中.所以只要SetUnhandledExceptionFilter 就能抓到 C++ 的异常了.

按C++标准,未处理的C++异常应当是触发unexpected.而MS 放出话说它的编译器只触发terminate.而在MFC 中居然terminate 都不触发了,直接变成了 SEH 而进入了MyCallBack.

部分源码:

#include "stdafx.h"
#include "DumpHandle.h"  
#include <stdlib.h>
#include <stdio.h>
#include <dbghelp.h>
#pragma comment(lib, "Dbghelp.lib")




LONG WINAPI DumpHandleFilterA(struct _EXCEPTION_POINTERS *lpExceptionInfo)
{
LONG ret = EXCEPTION_EXECUTE_HANDLER;
char szFileName[128] = {0};
SYSTEMTIME st = {0};
  
::GetLocalTime(&st); 
 
wsprintfA(szFileName, ("CrashAt[%04d-%02d-%02d-%02d-%02d-%02d-%02d-%02d].dmp"), 
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, rand()%100);
HANDLE hFile = ::CreateFileA(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION ExInfo;         
ExInfo.ThreadId = ::GetCurrentThreadId();       
ExInfo.ExceptionPointers = lpExceptionInfo;        
ExInfo.ClientPointers = false;       
// write the dump        
BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );         
if (bOK)
{
DumpDbgPrintA(("Create Dump File Success!/n")); 
DumpDbgMsgboxA("Create Dump File Success!/n");
}
else
{
DumpDbgPrintA(("MiniDumpWriteDump Failed: %d/n"), GetLastError() ); 
DumpDbgMsgboxA(("MiniDumpWriteDump Failed: %d/n"), GetLastError() );
}
::CloseHandle(hFile);
}
else
{
DumpDbgPrintA(("Create File %s Failed %d/n"), szFileName, GetLastError());
DumpDbgMsgboxA(("Create File %s Failed %d/n"), szFileName, GetLastError()); 
}
 
   
return ret;
}




void DumpDbgPrintA (char *fmt, ... )
{
va_list argptr;/* Argument list pointer*/
char str[1024*3] = {0};/* Buffer to build sting into*/


va_start (argptr, fmt);/* Initialize va_ functions*/
wvsprintfA (str, fmt, argptr);/* prints string to buffer*/
OutputDebugStringA(str);
va_end (argptr);/* Close va_ functions*/
}


void DumpDbgMsgboxA (char *fmt, ... )
{
va_list argptr;/* Argument list pointer*/
char str[1024*3] = {0};/* Buffer to build sting into*/


va_start (argptr, fmt);/* Initialize va_ functions*/
wvsprintfA (str, fmt, argptr);/* prints string to buffer*/
MessageBoxA (NULL, str, "Debug Message", 
MB_ICONINFORMATION | MB_OK);
va_end (argptr);/* Close va_ functions*/
}

posted on   DoubleLi  阅读(791)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2012-03-31 jQuery对select操作小结(遍历option,操作option)
点击右上角即可分享
微信分享提示