Fix HandleInvalidParameter/HandlePureVirtualCall to dynamically lookup the RtlCaptureContext symbol so the Windows exception handler will continue to work on Windows 2000. Patch by Jim Mathies <jmathies@mozilla.com> and Timothy Nikkel <tnikkel@gmail.com>. r=ted

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@637 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek 2010-08-02 13:56:29 +00:00
parent 0b814c1d2b
commit 0fdc829d32

View file

@ -37,6 +37,8 @@
#include "client/windows/handler/exception_handler.h" #include "client/windows/handler/exception_handler.h"
#include "common/windows/guid_string.h" #include "common/windows/guid_string.h"
typedef VOID (WINAPI *RtlCaptureContextPtr) (PCONTEXT pContextRecord);
namespace google_breakpad { namespace google_breakpad {
static const int kWaitForHandlerThreadMs = 60000; static const int kWaitForHandlerThreadMs = 60000;
@ -486,7 +488,14 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
EXCEPTION_RECORD exception_record = {}; EXCEPTION_RECORD exception_record = {};
CONTEXT exception_context = {}; CONTEXT exception_context = {};
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
RtlCaptureContext(&exception_context);
EXCEPTION_POINTERS* exinfo = NULL;
RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext");
if (fnRtlCaptureContext) {
fnRtlCaptureContext(&exception_context);
exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
// We store pointers to the the expression and function strings, // We store pointers to the the expression and function strings,
@ -499,16 +508,19 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
reinterpret_cast<ULONG_PTR>(&assertion.file); reinterpret_cast<ULONG_PTR>(&assertion.file);
exception_record.ExceptionInformation[2] = assertion.line; exception_record.ExceptionInformation[2] = assertion.line;
exinfo = &exception_ptrs;
}
bool success = false; bool success = false;
// In case of out-of-process dump generation, directly call // In case of out-of-process dump generation, directly call
// WriteMinidumpWithException since there is no separate thread running. // WriteMinidumpWithException since there is no separate thread running.
if (current_handler->IsOutOfProcess()) { if (current_handler->IsOutOfProcess()) {
success = current_handler->WriteMinidumpWithException( success = current_handler->WriteMinidumpWithException(
GetCurrentThreadId(), GetCurrentThreadId(),
&exception_ptrs, exinfo,
&assertion); &assertion);
} else { } else {
success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
&assertion); &assertion);
} }
@ -564,7 +576,14 @@ void ExceptionHandler::HandlePureVirtualCall() {
EXCEPTION_RECORD exception_record = {}; EXCEPTION_RECORD exception_record = {};
CONTEXT exception_context = {}; CONTEXT exception_context = {};
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
RtlCaptureContext(&exception_context);
EXCEPTION_POINTERS* exinfo = NULL;
RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext");
if (fnRtlCaptureContext) {
fnRtlCaptureContext(&exception_context);
exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
// We store pointers to the the expression and function strings, // We store pointers to the the expression and function strings,
@ -577,6 +596,9 @@ void ExceptionHandler::HandlePureVirtualCall() {
reinterpret_cast<ULONG_PTR>(&assertion.file); reinterpret_cast<ULONG_PTR>(&assertion.file);
exception_record.ExceptionInformation[2] = assertion.line; exception_record.ExceptionInformation[2] = assertion.line;
exinfo = &exception_ptrs;
}
bool success = false; bool success = false;
// In case of out-of-process dump generation, directly call // In case of out-of-process dump generation, directly call
// WriteMinidumpWithException since there is no separate thread running. // WriteMinidumpWithException since there is no separate thread running.
@ -584,10 +606,10 @@ void ExceptionHandler::HandlePureVirtualCall() {
if (current_handler->IsOutOfProcess()) { if (current_handler->IsOutOfProcess()) {
success = current_handler->WriteMinidumpWithException( success = current_handler->WriteMinidumpWithException(
GetCurrentThreadId(), GetCurrentThreadId(),
&exception_ptrs, exinfo,
&assertion); &assertion);
} else { } else {
success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
&assertion); &assertion);
} }