封装了一个C++类,当程序意外崩溃的时候可以生成dump文件,以便确定错误原因。
头文件:
1 //crash_dumper_w32.h
2
3 #ifndef _CRASH_DUMPER_H_
4
5 #define _CRASH_DUMPER_H_
6
7
8 #include <windows.h>
9
10 class CrashDumper
11
12 {
13
14 public:
15
16 CrashDumper();
17
18 ~CrashDumper();
19
20 static bool _PlaceHolder();
21
22 private:
23
24 LPTOP_LEVEL_EXCEPTION_FILTER m_OriginalFilter;
25
26 static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo);
27
28 };
29
30
31 namespace
32
33 {
34 const bool bPlaceHolder = CrashDumper::_PlaceHolder();
35
36 }
37
38 #endif
实现文件:
1 crash_dumper_w32.cpp
2
3
4
5 #include <windows.h>
6
7 #include <tchar.h>
8
9 #include <dbghelp.h>
10
11 #include <string>
12
13
14
15 #include "crash_dumper_w32.h"
16
17
18
19 #ifdef UNICODE
20
21 # define tstring wstring
22
23 #else
24
25 # define tstring string
26
27 #endif
28
29
30
31 #pragma comment(lib, "dbghelp.lib")
32
33
34
35 CrashDumper dumper;
36
37
38
39 CrashDumper::CrashDumper()
40
41 {
42
43 m_OriginalFilter = SetUnhandledExceptionFilter(ExceptionFilter);
44
45 }
46
47
48
49 CrashDumper::~CrashDumper()
50
51 {
52
53 SetUnhandledExceptionFilter(m_OriginalFilter);
54
55 }
56
57
58
59 LONG WINAPI CrashDumper::ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo)
60
61 {
62
63 bool bDumpOK = false;
64
65 DWORD dwProcess = GetCurrentProcessId();
66
67 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcess);
68
69 if (hProcess != INVALID_HANDLE_VALUE)
70
71 {
72
73 TCHAR szPath[MAX_PATH];
74
75 if (GetModuleFileName(NULL, szPath, sizeof(szPath)))
76
77 {
78
79 std::tstring strDumpFileName = szPath;
80
81 strDumpFileName += TEXT(".dmp");
82
83 HANDLE hFile = CreateFile(strDumpFileName.c_str(), FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, NULL, NULL);
84
85 if (hFile != INVALID_HANDLE_VALUE)
86
87 {
88
89 MINIDUMP_EXCEPTION_INFORMATION exception_information;
90
91 exception_information.ThreadId = GetCurrentThreadId();
92
93 exception_information.ExceptionPointers = ExceptionInfo;
94
95 exception_information.ClientPointers = TRUE;
96
97 if (MiniDumpWriteDump(hProcess, dwProcess, hFile, MiniDumpNormal, &exception_information, NULL, NULL))
98
99 {
100
101 bDumpOK = true;
102
103 }
104
105
106
107 CloseHandle(hFile);
108
109 }
110
111 }
112
113
114
115 CloseHandle(hProcess);
116
117 }
118
119
120
121 if (bDumpOK)
122
123 MessageBox(NULL, TEXT("本程序遇到未处理的异常,MiniDump文件已经生成在程序的运行目录。"), TEXT("提示"), MB_OK);
124
125 else
126
127 MessageBox(NULL, TEXT("本程序遇到未处理的异常,生成MiniDump文件失败。"), TEXT("提示"), MB_OK);
128
129
130
131 return EXCEPTION_EXECUTE_HANDLER;
132
133 }
134
135
136 bool CrashDumper::_PlaceHolder() {return true;}
代码很简单,唯一需要提一下的是下面的一句代码,这个技巧是为了解决当crash_dumper_w32.cpp文件被编译成单独的静态库在程序中使用不起作用的问题。
namespace
{
const bool bPlaceHolder = CrashDumper::_PlaceHolder();
}
之所以在静态库中.cpp中的代码不起作用,是因为没有代码去调用crash_dumper_w32.cpp的代码,链接的时候就被编译器给丢掉了。上面的语句在匿名空间中定义了一个变量,这样,每一个包含它的.cpp文件就“被迫”创建了一个不可访问的bPlaceHolder变量,而该变量又必须使用CrashDumper::_PlaceHolder()函数来初始化。crash_dumper_w32.cpp文件的代码就被强制链接进来了。
此外,如果是服务类型的程序,还可以在异常处理函数中增加自动启动新实例的功能,以保证服务不间断。
原文链接: https://www.cnblogs.com/FCoding/archive/2012/07/05/2578557.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/54440
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!