Issue 162 - handle pure virtual function calls in VC++. r=mento

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@166 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek 2007-05-10 17:12:14 +00:00
parent b44d391b53
commit b86e7ec7f0
3 changed files with 48 additions and 2 deletions

View File

@ -64,6 +64,7 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
minidump_write_dump_(NULL),
installed_handler_(install_handler),
previous_filter_(NULL),
previous_pch_(NULL),
handler_thread_(0),
handler_critical_section_(),
handler_start_semaphore_(NULL),
@ -124,6 +125,8 @@ ExceptionHandler::ExceptionHandler(const wstring &dump_path,
previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
#endif // _MSC_VER >= 1400
previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
LeaveCriticalSection(&handler_stack_critical_section_);
}
}
@ -142,6 +145,8 @@ ExceptionHandler::~ExceptionHandler() {
_set_invalid_parameter_handler(previous_iph_);
#endif // _MSC_VER >= 1400
_set_purecall_handler(previous_pch_);
if (handler_stack_->back() == this) {
handler_stack_->pop_back();
} else {
@ -233,6 +238,7 @@ class AutoExceptionHandler {
#if _MSC_VER >= 1400 // MSVC 2005/8
_set_invalid_parameter_handler(handler_->previous_iph_);
#endif // _MSC_VER >= 1400
_set_purecall_handler(handler_->previous_pch_);
}
~AutoExceptionHandler() {
@ -241,6 +247,7 @@ class AutoExceptionHandler {
#if _MSC_VER >= 1400 // MSVC 2005/8
_set_invalid_parameter_handler(ExceptionHandler::HandleInvalidParameter);
#endif // _MSC_VER >= 1400
_set_purecall_handler(ExceptionHandler::HandlePureVirtualCall);
EnterCriticalSection(&ExceptionHandler::handler_stack_critical_section_);
--ExceptionHandler::handler_stack_index_;
@ -349,6 +356,33 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t *expression,
}
#endif // _MSC_VER >= 1400
// static
void ExceptionHandler::HandlePureVirtualCall() {
AutoExceptionHandler auto_exception_handler;
ExceptionHandler *current_handler = auto_exception_handler.get_handler();
MDRawAssertionInfo assertion;
memset(&assertion, 0, sizeof(assertion));
assertion.type = MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL;
if (!current_handler->WriteMinidumpOnHandlerThread(NULL, &assertion)) {
if (current_handler->previous_pch_) {
// The handler didn't fully handle the exception. Give it to the
// previous purecall handler.
current_handler->previous_pch_();
} else {
// If there's no previous handler, return and let _purecall handle it.
// This will just put up an assertion dialog.
return;
}
}
// The handler either took care of the invalid parameter problem itself,
// or passed it on to another handler. "Swallow" it by exiting, paralleling
// the behavior of "swallowing" exceptions.
exit(0);
}
bool ExceptionHandler::WriteMinidumpOnHandlerThread(
EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion) {
EnterCriticalSection(&handler_critical_section_);

View File

@ -183,6 +183,10 @@ class ExceptionHandler {
uintptr_t reserved);
#endif // _MSC_VER >= 1400
// This function will be called by the CRT when a pure virtual
// function is called.
static void HandlePureVirtualCall();
// This is called on the exception thread or on another thread that
// the user wishes to produce a dump from. It calls
// WriteMinidumpWithException on the handler thread, avoiding stack
@ -254,6 +258,10 @@ class ExceptionHandler {
_invalid_parameter_handler previous_iph_;
#endif // _MSC_VER >= 1400
// The CRT allows you to override the default handler for pure
// virtual function calls.
_purecall_handler previous_pch_;
// The exception handler thread.
HANDLE handler_thread_;

View File

@ -1046,13 +1046,17 @@ typedef struct {
u_int32_t type;
} MDRawAssertionInfo;
/* For (MDRawAssertionInfo).info: */
/* For (MDRawAssertionInfo).type: */
typedef enum {
MD_ASSERTION_INFO_TYPE_UNKNOWN = 0,
/* Used for assertions that would be raised by the MSVC CRT but are
* directed to an invalid parameter handler instead. */
MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER
MD_ASSERTION_INFO_TYPE_INVALID_PARAMETER,
/* Used for assertions that would be raised by the MSVC CRT but are
* directed to a pure virtual call handler instead. */
MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL
} MDAssertionInfoData;
#if defined(_MSC_VER)