1
// Copyright (c) 2007, Google Inc.
2
// All rights reserved.
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are
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
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.
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.
30
// Author: Alfred Peng
32
#ifndef CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
33
#define CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__
39
#include "client/solaris/handler/minidump_generator.h"
41
namespace google_breakpad {
48
// ExceptionHandler can write a minidump file when an exception occurs,
49
// or when WriteMinidump() is called explicitly by your program.
51
// To have the exception handler write minidumps when an uncaught exception
52
// (crash) occurs, you should create an instance early in the execution
53
// of your program, and keep it around for the entire time you want to
54
// have crash handling active (typically, until shutdown).
55
// (NOTE): There should be only one this kind of exception handler
56
// object per process.
58
// If you want to write minidumps without installing the exception handler,
59
// you can create an ExceptionHandler with install_handler set to false,
60
// then call WriteMinidump. You can also use this technique if you want to
61
// use different minidump callbacks for different call sites.
63
// In either case, a callback function is called when a minidump is written,
64
// which receives the unqiue id of the minidump. The caller can use this
65
// id to collect and write additional application state, and to launch an
66
// external crash-reporting application.
68
// Caller should try to make the callbacks as crash-friendly as possible,
69
// it should avoid use heap memory allocation as much as possible.
71
class ExceptionHandler {
73
// A callback function to run before Breakpad performs any substantial
74
// processing of an exception. A FilterCallback is called before writing
75
// a minidump. context is the parameter supplied by the user as
76
// callback_context when the handler was created.
78
// If a FilterCallback returns true, Breakpad will continue processing,
79
// attempting to write a minidump. If a FilterCallback returns false,
80
// Breakpad will immediately report the exception as unhandled without
81
// writing a minidump, allowing another handler the opportunity to handle it.
82
typedef bool (*FilterCallback)(void *context);
84
// A callback function to run after the minidump has been written.
85
// minidump_id is a unique id for the dump, so the minidump
86
// file is <dump_path>/<minidump_id>.dmp. context is the parameter supplied
87
// by the user as callback_context when the handler was created. succeeded
88
// indicates whether a minidump file was successfully written.
90
// If an exception occurred and the callback returns true, Breakpad will
91
// treat the exception as fully-handled, suppressing any other handlers from
92
// being notified of the exception. If the callback returns false, Breakpad
93
// will treat the exception as unhandled, and allow another handler to handle
94
// it. If there are no other handlers, Breakpad will report the exception to
95
// the system as unhandled, allowing a debugger or native crash dialog the
96
// opportunity to handle the exception. Most callback implementations
97
// should normally return the value of |succeeded|, or when they wish to
98
// not report an exception of handled, false. Callbacks will rarely want to
99
// return true directly (unless |succeeded| is true).
100
typedef bool (*MinidumpCallback)(const char *dump_path,
101
const char *minidump_id,
105
// Creates a new ExceptionHandler instance to handle writing minidumps.
106
// Before writing a minidump, the optional filter callback will be called.
107
// Its return value determines whether or not Breakpad should write a
108
// minidump. Minidump files will be written to dump_path, and the optional
109
// callback is called after writing the dump file, as described above.
110
// If install_handler is true, then a minidump will be written whenever
111
// an unhandled exception occurs. If it is false, minidumps will only
112
// be written when WriteMinidump is called.
113
ExceptionHandler(const string &dump_path,
114
FilterCallback filter, MinidumpCallback callback,
115
void *callback_context,
116
bool install_handler);
119
// Get and Set the minidump path.
120
string dump_path() const { return dump_path_; }
121
void set_dump_path(const string &dump_path) {
122
dump_path_ = dump_path;
123
dump_path_c_ = dump_path_.c_str();
126
// Writes a minidump immediately. This can be used to capture the
127
// execution state independently of a crash. Returns true on success.
128
bool WriteMinidump();
130
// Convenience form of WriteMinidump which does not require an
131
// ExceptionHandler instance.
132
static bool WriteMinidump(const string &dump_path,
133
MinidumpCallback callback,
134
void *callback_context);
137
// Setup crash handler.
139
// Setup signal handler for a signal.
140
void SetupHandler(int signo);
141
// Teardown the handler for a signal.
142
void TeardownHandler(int signo);
143
// Teardown all handlers.
144
void TeardownAllHandlers();
146
// Runs the main loop for the exception handler thread.
147
static void* ExceptionHandlerThreadMain(void *lpParameter);
150
static void HandleException(int signo);
152
// Write all the information to the dump file.
153
// If called from a signal handler, sighandler_ebp is the ebp of
154
// that signal handler's frame, and sig_ctx is an out parameter
155
// that will be set to point at the ucontext_t that was placed
156
// on the stack by the kernel. You can pass zero and NULL
157
// for the second and third parameters if you are not calling
158
// this from a signal handler.
159
bool InternalWriteMinidump(int signo, uintptr_t sighandler_ebp,
160
ucontext_t **sig_ctx);
163
// The callbacks before and after writing the dump file.
164
FilterCallback filter_;
165
MinidumpCallback callback_;
166
void *callback_context_;
168
// The directory in which a minidump will be written, set by the dump_path
169
// argument to the constructor, or set_dump_path.
171
// C style dump path. Keep this when setting dump path, since calling
172
// c_str() of std::string when crashing may not be safe.
173
const char *dump_path_c_;
175
// True if the ExceptionHandler installed an unhandled exception filter
176
// when created (with an install_handler parameter set to true).
177
bool installed_handler_;
179
// Keep the previous handlers for the signal.
180
typedef void (*sighandler_t)(int);
181
std::map<int, sighandler_t> old_handlers_;
183
// The global exception handler stack. This is need becuase there may exist
184
// multiple ExceptionHandler instances in a process. Each will have itself
185
// registered in this stack.
186
static std::vector<ExceptionHandler *> *handler_stack_;
187
// The index of the handler that should handle the next exception.
188
static int handler_stack_index_;
189
static pthread_mutex_t handler_stack_mutex_;
191
// The minidump generator.
192
MinidumpGenerator minidump_generator_;
194
// disallow copy ctor and operator=
195
explicit ExceptionHandler(const ExceptionHandler &);
196
void operator=(const ExceptionHandler &);
199
} // namespace google_breakpad
201
#endif // CLIENT_SOLARIS_HANDLER_EXCEPTION_HANDLER_H__