aboutsummaryrefslogtreecommitdiff
path: root/src/client/windows
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-12-21 22:09:56 +0000
committermark@chromium.org <mark@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-12-21 22:09:56 +0000
commit5951dd28afc3adb82ee21926c7f6cf46f9f15b87 (patch)
tree7aa54fefdc3b56cf028d26e2ff05806aa1b5274f /src/client/windows
parentReplace readlink calls with a safer version that guarantees NULL-termination. (diff)
downloadbreakpad-5951dd28afc3adb82ee21926c7f6cf46f9f15b87.tar.xz
Eliminate another source of UnspecifiedStackSignature crash dumps.
Manufacturing an exception record improves the crash reporting, since then the crashes get bucketed by the call stack leading to the dump, instead of all falling into a misc bucket that nobody ever looks at. Currently these are occuring through e.g. dumps from the base watchdog. Link against RtlCaptureContext, as the function has been documented as available from Windows XP [http://msdn.microsoft.com/en-us/library/windows/desktop/ms680591(v=vs.85).aspx]. Patch by Siggi Asgeirsson <siggi@chromium.org> git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@897 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/windows')
-rw-r--r--src/client/windows/handler/exception_handler.cc83
1 files changed, 38 insertions, 45 deletions
diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc
index ec5397dc..7ce2ca93 100644
--- a/src/client/windows/handler/exception_handler.cc
+++ b/src/client/windows/handler/exception_handler.cc
@@ -39,8 +39,6 @@
#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;
@@ -498,27 +496,19 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
CONTEXT exception_context = {};
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
- EXCEPTION_POINTERS* exinfo = NULL;
-
- RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
- GetProcAddress(GetModuleHandleW(L"kernel32"), "RtlCaptureContext");
- if (fnRtlCaptureContext) {
- fnRtlCaptureContext(&exception_context);
+ ::RtlCaptureContext(&exception_context);
- exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
+ exception_record.ExceptionCode = STATUS_INVALID_PARAMETER;
- // 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;
- }
+ // 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;
bool success = false;
// In case of out-of-process dump generation, directly call
@@ -526,10 +516,10 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
if (current_handler->IsOutOfProcess()) {
success = current_handler->WriteMinidumpWithException(
GetCurrentThreadId(),
- exinfo,
+ &exception_ptrs,
&assertion);
} else {
- success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
+ success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
&assertion);
}
@@ -586,27 +576,19 @@ void ExceptionHandler::HandlePureVirtualCall() {
CONTEXT exception_context = {};
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
- EXCEPTION_POINTERS* exinfo = NULL;
+ ::RtlCaptureContext(&exception_context);
- 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,
- // 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;
- }
+ // 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;
bool success = false;
// In case of out-of-process dump generation, directly call
@@ -615,10 +597,10 @@ void ExceptionHandler::HandlePureVirtualCall() {
if (current_handler->IsOutOfProcess()) {
success = current_handler->WriteMinidumpWithException(
GetCurrentThreadId(),
- exinfo,
+ &exception_ptrs,
&assertion);
} else {
- success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
+ success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
&assertion);
}
@@ -678,7 +660,18 @@ bool ExceptionHandler::WriteMinidumpOnHandlerThread(
}
bool ExceptionHandler::WriteMinidump() {
- return WriteMinidumpForException(NULL);
+ // Make up an exception record for the current thread and CPU context
+ // to make it possible for the crash processor to classify these
+ // as do regular crashes, and to make it humane for developers to
+ // analyze them.
+ EXCEPTION_RECORD exception_record = {};
+ CONTEXT exception_context = {};
+ EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
+
+ ::RtlCaptureContext(&exception_context);
+ exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
+
+ return WriteMinidumpForException(&exception_ptrs);
}
bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS* exinfo) {