From 0fdc829d3233917185e179c62a12ecd6d3df9e42 Mon Sep 17 00:00:00 2001 From: "ted.mielczarek" Date: Mon, 2 Aug 2010 13:56:29 +0000 Subject: 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 and Timothy Nikkel . r=ted git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@637 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/client/windows/handler/exception_handler.cc | 78 ++++++++++++++++--------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc index 27c28e76..7af20ce7 100644 --- a/src/client/windows/handler/exception_handler.cc +++ b/src/client/windows/handler/exception_handler.cc @@ -37,6 +37,8 @@ #include "client/windows/handler/exception_handler.h" #include "common/windows/guid_string.h" +typedef VOID (WINAPI *RtlCaptureContextPtr) (PCONTEXT pContextRecord); + namespace google_breakpad { static const int kWaitForHandlerThreadMs = 60000; @@ -486,18 +488,28 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression, EXCEPTION_RECORD exception_record = {}; CONTEXT exception_context = {}; EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; - RtlCaptureContext(&exception_context); - exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; - - // We store pointers to the the expression and function strings, - // and the line as exception parameters to make them easy to - // access by the developer on the far side. - exception_record.NumberParameters = 3; - exception_record.ExceptionInformation[0] = - reinterpret_cast(&assertion.expression); - exception_record.ExceptionInformation[1] = - reinterpret_cast(&assertion.file); - exception_record.ExceptionInformation[2] = assertion.line; + + EXCEPTION_POINTERS* exinfo = NULL; + + RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr) + GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext"); + if (fnRtlCaptureContext) { + fnRtlCaptureContext(&exception_context); + + exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; + + // We store pointers to the the expression and function strings, + // and the line as exception parameters to make them easy to + // access by the developer on the far side. + exception_record.NumberParameters = 3; + exception_record.ExceptionInformation[0] = + reinterpret_cast(&assertion.expression); + exception_record.ExceptionInformation[1] = + reinterpret_cast(&assertion.file); + exception_record.ExceptionInformation[2] = assertion.line; + + exinfo = &exception_ptrs; + } bool success = false; // In case of out-of-process dump generation, directly call @@ -505,10 +517,10 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression, if (current_handler->IsOutOfProcess()) { success = current_handler->WriteMinidumpWithException( GetCurrentThreadId(), - &exception_ptrs, + exinfo, &assertion); } else { - success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, + success = current_handler->WriteMinidumpOnHandlerThread(exinfo, &assertion); } @@ -564,18 +576,28 @@ void ExceptionHandler::HandlePureVirtualCall() { EXCEPTION_RECORD exception_record = {}; CONTEXT exception_context = {}; EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; - RtlCaptureContext(&exception_context); - exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; - - // We store pointers to the the expression and function strings, - // and the line as exception parameters to make them easy to - // access by the developer on the far side. - exception_record.NumberParameters = 3; - exception_record.ExceptionInformation[0] = - reinterpret_cast(&assertion.expression); - exception_record.ExceptionInformation[1] = - reinterpret_cast(&assertion.file); - exception_record.ExceptionInformation[2] = assertion.line; + + EXCEPTION_POINTERS* exinfo = NULL; + + RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr) + GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext"); + if (fnRtlCaptureContext) { + fnRtlCaptureContext(&exception_context); + + exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; + + // We store pointers to the the expression and function strings, + // and the line as exception parameters to make them easy to + // access by the developer on the far side. + exception_record.NumberParameters = 3; + exception_record.ExceptionInformation[0] = + reinterpret_cast(&assertion.expression); + exception_record.ExceptionInformation[1] = + reinterpret_cast(&assertion.file); + exception_record.ExceptionInformation[2] = assertion.line; + + exinfo = &exception_ptrs; + } bool success = false; // In case of out-of-process dump generation, directly call @@ -584,10 +606,10 @@ void ExceptionHandler::HandlePureVirtualCall() { if (current_handler->IsOutOfProcess()) { success = current_handler->WriteMinidumpWithException( GetCurrentThreadId(), - &exception_ptrs, + exinfo, &assertion); } else { - success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, + success = current_handler->WriteMinidumpOnHandlerThread(exinfo, &assertion); } -- cgit v1.2.1