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

[Windows编程] 如何捕捉程序异常/crash 并生成 dump 文件

前面介绍如如何用WinDBG 生成crash dump 《WinDBG 技巧:如何生成Dump 文件(.dump 命令) 》,但是用户机器上通常不安装WinDBG, 而且多数用户也不知道怎么使用WinDBG。 所以最好是自己程序里面能够捕捉exception/crash,并且生成crash dump,然后通过网络传回到自己服务器。

捕捉exception 可以用API 函数 SetUnhandledExceptionFilter 。生成crash dump 可以用DbgHelp.dll 里面的MiniDumpWriteDump 函数。

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter( __in LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter );

BOOL WINAPI MiniDumpWriteDump( __in HANDLE hProcess, __in DWORD ProcessId, __in HANDLE hFile, __in MINIDUMP_TYPE DumpType, __in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, __in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, __in PMINIDUMP_CALLBACK_INFORMATION CallbackParam );

代码示例:

#include <dbghelp.h> #include <shellapi.h> #include <shlobj.h> // 自定义的exectpion filter LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionPointers) { SetErrorMode( SEM_NOGPFAULTERRORBOX ); //收集信息 CStringW strBuild; strBuild.Format(L"Build: %s %s", __DATE__, __TIME__); CStringW strError; HMODULE hModule; WCHAR szModuleName[MAX_PATH] = L""; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)pExceptionPointers->ExceptionRecord->ExceptionAddress, &hModule); GetModuleFileName(hModule, szModuleName, ARRAYSIZE(szModuleName)); strError.AppenedFormat(L"%s %d , %d ,%d.", szModuleName,pExceptionPointers->ExceptionRecord->ExceptionCode, pExceptionPointers->ExceptionRecord->ExceptionFlags, pExceptionPointers->ExceptionRecord->ExceptionAddress); //生成 mini crash dump BOOL bMiniDumpSuccessful; WCHAR szPath[MAX_PATH]; WCHAR szFileName[MAX_PATH]; WCHAR* szAppName = L"AppName"; WCHAR* szVersion = L"v1.0"; DWORD dwBufferSize = MAX_PATH; HANDLE hDumpFile; SYSTEMTIME stLocalTime; MINIDUMP_EXCEPTION_INFORMATION ExpParam; GetLocalTime( &stLocalTime ); GetTempPath( dwBufferSize, szPath ); StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName ); CreateDirectory( szFileName, NULL ); StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", szPath, szAppName, szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, GetCurrentProcessId(), GetCurrentThreadId()); hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); MINIDUMP_USER_STREAM UserStream[2]; MINIDUMP_USER_STREAM_INFORMATION UserInfo; UserInfo.UserStreamCount = 1; UserInfo.UserStreamArray = UserStream; UserStream[0].Type = CommentStreamW; UserStream[0].BufferSize = strBuild.GetLength()*sizeof(WCHAR); UserStream[0].Buffer = strBuild.GetBuffer(); UserStream[1].Type = CommentStreamW; UserStream[1].BufferSize = strError.GetLength()*sizeof(WCHAR); UserStream[1].Buffer = strError.GetBuffer(); ExpParam.ThreadId = GetCurrentThreadId(); ExpParam.ExceptionPointers = pExceptionPointers; ExpParam.ClientPointers = TRUE; MINIDUMP_TYPE MiniDumpWithDataSegs = MiniDumpNormal | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory | MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo; bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL); // 上传mini dump 到自己服务器(略) ... return EXCEPTION_CONTINUE_SEARCH; //或者 EXCEPTION_EXECUTE_HANDLER 关闭程序 } int _tmain() { // 设置 execption filter SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); .... return 0; }

相关文章:

  • zed graph使用经验
  • vim语法高亮
  • vbscript脚本用二进制方式读写文件
  • 15个最佳Flash物理游戏
  • ARX 反回曲线上一定距离的点 函数
  • 2008主流数据库产品回顾与展望
  • ARX 沿着多段线绘制一定距离,递归执行
  • WinDBG 技巧: 显示GetLastError() 错误码 (!gle命令)
  • C# 窗体间传值总结
  • 诺基亚5800XM 承认质量缺陷
  • ASP.NET Web Application 中使用 Unity 依赖注入容器
  • ARX 多段线的合并
  • 参加ESB沙龙
  • 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
  • Unix哲学基础
  • JS 中的深拷贝与浅拷贝
  • [译] 怎样写一个基础的编译器
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 2017-09-12 前端日报
  • Babel配置的不完全指南
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • classpath对获取配置文件的影响
  • Fastjson的基本使用方法大全
  • javascript面向对象之创建对象
  • Less 日常用法
  • PermissionScope Swift4 兼容问题
  • rabbitmq延迟消息示例
  • 大主子表关联的性能优化方法
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 浮现式设计
  • 猴子数据域名防封接口降低小说被封的风险
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 白色的风信子
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 正则表达式-基础知识Review
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • # 达梦数据库知识点
  • #pragma once与条件编译
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (rabbitmq的高级特性)消息可靠性
  • (zhuan) 一些RL的文献(及笔记)
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)ORM
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .naturalWidth 和naturalHeight属性,
  • .Net 4.0并行库实用性演练
  • .NET 4.0中的泛型协变和反变
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [52PJ] Java面向对象笔记(转自52 1510988116)
  • [C++] 统计程序耗时
  • [HeMIM]Cl,[AeMIM]Br,[CeEIM]Cl,([HO-PECH-MIM]Cl,[HOOC-PECH-MIM]Cl改性酚醛树脂
  • [Hive] 常见函数
  • [IE编程] 多页面基于IE内核浏览器的代码示例