aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2007-07-02 19:41:05 +0000
committermmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2007-07-02 19:41:05 +0000
commit6a844b1d85be2804e1cbf6771f4249f5172b08c7 (patch)
tree035f7b2a349eaf2b3ce1c9ac3f41871c195bc060
parentIssue 190 - 32 bit build fails on a 64 bit Linux system. Patch by wgianopoul... (diff)
downloadbreakpad-6a844b1d85be2804e1cbf6771f4249f5172b08c7.tar.xz
Allow finer control over installed handler types (#193). r=ted.mielczarek
http://groups.google.com/group/google-breakpad-dev/browse_thread/thread/992a1bb09dc58a32 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@193 4c0a9323-5329-0410-9bdc-e9ce6186880e
-rw-r--r--src/client/windows/handler/exception_handler.cc39
-rw-r--r--src/client/windows/handler/exception_handler.h38
-rw-r--r--src/processor/testdata/test_app.cc4
3 files changed, 53 insertions, 28 deletions
diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc
index d2c6e7d0..2d7bc57c 100644
--- a/src/client/windows/handler/exception_handler.cc
+++ b/src/client/windows/handler/exception_handler.cc
@@ -50,7 +50,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
FilterCallback filter,
MinidumpCallback callback,
void *callback_context,
- bool install_handler)
+ HandlerType handler_types)
: filter_(filter),
callback_(callback),
callback_context_(callback_context),
@@ -62,7 +62,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
next_minidump_path_c_(NULL),
dbghelp_module_(NULL),
minidump_write_dump_(NULL),
- installed_handler_(install_handler),
+ handler_types_(handler_types),
previous_filter_(NULL),
previous_pch_(NULL),
handler_thread_(0),
@@ -82,11 +82,10 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
set_dump_path(dump_path);
// Set synchronization primitives and the handler thread. Each
- // ExceptionHandler object gets its own handler thread, even if
- // install_handler is false, because that's the only way to reliably
- // guarantee sufficient stack space in an exception, and the only way to
- // get a snapshot of the requesting thread's context outside of an
- // exception.
+ // ExceptionHandler object gets its own handler thread because that's the
+ // only way to reliably guarantee sufficient stack space in an exception,
+ // and it allows an easy way to get a snapshot of the requesting thread's
+ // context outside of an exception.
InitializeCriticalSection(&handler_critical_section_);
handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
@@ -105,7 +104,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
GetProcAddress(dbghelp_module_, "MiniDumpWriteDump"));
}
- if (install_handler) {
+ if (handler_types != HANDLER_NONE) {
if (!handler_stack_critical_section_initialized_) {
InitializeCriticalSection(&handler_stack_critical_section_);
handler_stack_critical_section_initialized_ = true;
@@ -119,13 +118,17 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
handler_stack_ = new vector<ExceptionHandler *>();
}
handler_stack_->push_back(this);
- previous_filter_ = SetUnhandledExceptionFilter(HandleException);
+
+ if (handler_types & HANDLER_EXCEPTION)
+ previous_filter_ = SetUnhandledExceptionFilter(HandleException);
#if _MSC_VER >= 1400 // MSVC 2005/8
- previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
+ if (handler_types & HANDLER_INVALID_PARAMETER)
+ previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
#endif // _MSC_VER >= 1400
- previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
+ if (handler_types & HANDLER_PURECALL)
+ previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
LeaveCriticalSection(&handler_stack_critical_section_);
}
@@ -136,16 +139,19 @@ ExceptionHandler::~ExceptionHandler() {
FreeLibrary(dbghelp_module_);
}
- if (installed_handler_) {
+ if (handler_types_ != HANDLER_NONE) {
EnterCriticalSection(&handler_stack_critical_section_);
- SetUnhandledExceptionFilter(previous_filter_);
+ if (handler_types_ & HANDLER_EXCEPTION)
+ SetUnhandledExceptionFilter(previous_filter_);
#if _MSC_VER >= 1400 // MSVC 2005/8
- _set_invalid_parameter_handler(previous_iph_);
+ if (handler_types_ & HANDLER_INVALID_PARAMETER)
+ _set_invalid_parameter_handler(previous_iph_);
#endif // _MSC_VER >= 1400
- _set_purecall_handler(previous_pch_);
+ if (handler_types_ & HANDLER_PURECALL)
+ _set_purecall_handler(previous_pch_);
if (handler_stack_->back() == this) {
handler_stack_->pop_back();
@@ -423,7 +429,8 @@ bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS *exinfo) {
bool ExceptionHandler::WriteMinidump(const wstring &dump_path,
MinidumpCallback callback,
void *callback_context) {
- ExceptionHandler handler(dump_path, NULL, callback, callback_context, false);
+ ExceptionHandler handler(dump_path, NULL, callback, callback_context,
+ HANDLER_NONE);
return handler.WriteMinidump();
}
diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h
index a9eccd6b..c2d55609 100644
--- a/src/client/windows/handler/exception_handler.h
+++ b/src/client/windows/handler/exception_handler.h
@@ -119,17 +119,33 @@ class ExceptionHandler {
MDRawAssertionInfo *assertion,
bool succeeded);
+ // HandlerType specifies which types of handlers should be installed, if
+ // any. Use HANDLER_NONE for an ExceptionHandler that remains idle,
+ // without catching any failures on its own. This type of handler may
+ // still be triggered by calling WriteMinidump. Otherwise, use a
+ // combination of the other HANDLER_ values, or HANDLER_ALL to install
+ // all handlers.
+ enum HandlerType {
+ HANDLER_NONE = 0,
+ HANDLER_EXCEPTION = 1 << 0, // SetUnhandledExceptionFilter
+ HANDLER_INVALID_PARAMETER = 1 << 1, // _set_invalid_parameter_handler
+ HANDLER_PURECALL = 1 << 2, // _set_purecall_handler
+ HANDLER_ALL = HANDLER_EXCEPTION |
+ HANDLER_INVALID_PARAMETER |
+ HANDLER_PURECALL
+ };
+
// Creates a new ExceptionHandler instance to handle writing minidumps.
// Before writing a minidump, the optional filter callback will be called.
- // Its return value determines whether or not Breakpad should write a minidump.
- // Minidump files will be written to dump_path, and the optional callback
- // is called after writing the dump file, as described above.
- // If install_handler is true, then a minidump will be written whenever
- // an unhandled exception occurs. If it is false, minidumps will only
- // be written when WriteMinidump is called.
+ // Its return value determines whether or not Breakpad should write a
+ // minidump. Minidump files will be written to dump_path, and the optional
+ // callback is called after writing the dump file, as described above.
+ // handler_types specifies the types of handlers that should be installed.
ExceptionHandler(const wstring &dump_path,
- FilterCallback filter, MinidumpCallback callback,
- void *callback_context, bool install_handler);
+ FilterCallback filter,
+ MinidumpCallback callback,
+ void *callback_context,
+ HandlerType handler_types);
~ExceptionHandler();
// Get and set the minidump path.
@@ -244,9 +260,9 @@ class ExceptionHandler {
HMODULE dbghelp_module_;
MiniDumpWriteDump_type minidump_write_dump_;
- // True if the ExceptionHandler installed an unhandled exception filter
- // when created (with an install_handler parameter set to true).
- bool installed_handler_;
+ // Tracks the handler types that were installed according to the
+ // handler_types constructor argument.
+ HandlerType handler_types_;
// When installed_handler_ is true, previous_filter_ is the unhandled
// exception filter that was set prior to installing ExceptionHandler as
diff --git a/src/processor/testdata/test_app.cc b/src/processor/testdata/test_app.cc
index 0d2a3394..e2b9c3a9 100644
--- a/src/processor/testdata/test_app.cc
+++ b/src/processor/testdata/test_app.cc
@@ -61,7 +61,9 @@ static void CrashFunction() {
} // namespace
int main(int argc, char **argv) {
- google_breakpad::ExceptionHandler eh(L".", NULL, callback, NULL, true);
+ google_breakpad::ExceptionHandler eh(
+ L".", NULL, callback, NULL,
+ google_breakpad::ExceptionHandler::HANDLER_ALL);
CrashFunction();
printf("did not crash?\n");
return 0;