blob: 7acb5853ea13bb264e29de615a290f23d149a6d6 [file] [log] [blame]
bryner1217c1f2006-09-27 01:00:32 +00001// Copyright (c) 2006, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// ExceptionHandler can write a minidump file when an exception occurs,
31// or when WriteMinidump() is called explicitly by your program.
32//
33// To have the exception handler write minidumps when an uncaught exception
34// (crash) occurs, you should create an instance early in the execution
35// of your program, and keep it around for the entire time you want to
36// have crash handling active (typically, until shutdown).
37//
38// If you want to write minidumps without installing the exception handler,
39// you can create an ExceptionHandler with install_handler set to false,
40// then call WriteMinidump. You can also use this technique if you want to
41// use different minidump callbacks for different call sites.
42//
43// In either case, a callback function is called when a minidump is written,
44// which receives the unqiue id of the minidump. The caller can use this
45// id to collect and write additional application state, and to launch an
46// external crash-reporting application.
47//
48// It is important that creation and destruction of ExceptionHandler objects
49// be nested cleanly, when using install_handler = true.
50// Avoid the following pattern:
51// ExceptionHandler *e = new ExceptionHandler(...);
52// ExceptionHandler *f = new ExceptionHandler(...);
53// delete e;
54// This will put the exception filter stack into an inconsistent state.
55
56#ifndef CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
57#define CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
58
59#include <windows.h>
60#include <dbghelp.h>
61
62#include <string>
63
64namespace google_airbag {
65
66using std::wstring;
67
68class ExceptionHandler {
69 public:
70 // A callback function to run after the minidump has been written.
71 // minidump_id is a unique id for the dump, so the minidump
72 // file is <dump_path>\<minidump_id>.dmp. succeeded indicates whether
73 // a minidump file was successfully written.
74 typedef void (*MinidumpCallback)(const wstring &minidump_id,
75 void *context, bool succeeded);
76
77 // Creates a new ExceptionHandler instance to handle writing minidumps.
78 // Minidump files will be written to dump_path, and the optional callback
79 // is called after writing the dump file, as described above.
80 // If install_handler is true, then a minidump will be written whenever
81 // an unhandled exception occurs. If it is false, minidumps will only
82 // be written when WriteMinidump is called.
83 ExceptionHandler(const wstring &dump_path, MinidumpCallback callback,
84 void *callback_context, bool install_handler);
85 ~ExceptionHandler();
86
87 // Writes a minidump immediately. This can be used to capture the
88 // execution state independently of a crash. Returns true on success.
89 bool WriteMinidump();
90
91 // Convenience form of WriteMinidump which does not require an
92 // ExceptionHandler instance.
93 static bool WriteMinidump(const wstring &dump_path,
94 MinidumpCallback callback, void *callback_context);
95
96 private:
97 // Function pointer type for MiniDumpWriteDump, which is looked up
98 // dynamically.
99 typedef BOOL (WINAPI *MiniDumpWriteDump_type)(
100 HANDLE hProcess,
101 DWORD dwPid,
102 HANDLE hFile,
103 MINIDUMP_TYPE DumpType,
104 CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
105 CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
106 CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
107
108 // This function does the actual writing of a minidump.
109 bool WriteMinidumpWithException(EXCEPTION_POINTERS *exinfo);
110
111 // Called when an unhandled exception occurs.
112 static LONG WINAPI HandleException(EXCEPTION_POINTERS *exinfo);
113
114 // Generates a new ID and stores it in next_minidump_id_.
115 void UpdateNextID();
116
117 MinidumpCallback callback_;
118 void *callback_context_;
119
120 wstring dump_path_;
121 RPC_WSTR next_minidump_id_;
122
123 HMODULE dbghelp_module_;
124 MiniDumpWriteDump_type minidump_write_dump_;
125
126 ExceptionHandler *previous_handler_; // current_handler_ before us
127 LPTOP_LEVEL_EXCEPTION_FILTER previous_filter_;
128
129 // the currently-installed ExceptionHandler, of which there can be only 1
130 static ExceptionHandler *current_handler_;
131
132 // disallow copy ctor and operator=
133 explicit ExceptionHandler(const ExceptionHandler &);
134 void operator=(const ExceptionHandler &);
135};
136
137} // namespace google_airbag
138
139#endif // CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__