aboutsummaryrefslogtreecommitdiff
path: root/src/client/windows/handler
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/windows/handler')
-rw-r--r--src/client/windows/handler/exception_handler.cc78
1 files 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<ULONG_PTR>(&assertion.expression);
- exception_record.ExceptionInformation[1] =
- reinterpret_cast<ULONG_PTR>(&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<ULONG_PTR>(&assertion.expression);
+ exception_record.ExceptionInformation[1] =
+ reinterpret_cast<ULONG_PTR>(&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<ULONG_PTR>(&assertion.expression);
- exception_record.ExceptionInformation[1] =
- reinterpret_cast<ULONG_PTR>(&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<ULONG_PTR>(&assertion.expression);
+ exception_record.ExceptionInformation[1] =
+ reinterpret_cast<ULONG_PTR>(&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);
}