mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-03-01 19:38:01 +00:00
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
This commit is contained in:
parent
ae5193c24e
commit
5951dd28af
|
@ -39,8 +39,6 @@
|
||||||
#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;
|
||||||
|
@ -498,27 +496,19 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
|
||||||
CONTEXT exception_context = {};
|
CONTEXT exception_context = {};
|
||||||
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
|
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
|
||||||
|
|
||||||
EXCEPTION_POINTERS* exinfo = NULL;
|
::RtlCaptureContext(&exception_context);
|
||||||
|
|
||||||
RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
|
exception_record.ExceptionCode = STATUS_INVALID_PARAMETER;
|
||||||
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
|
||||||
// We store pointers to the the expression and function strings,
|
// access by the developer on the far side.
|
||||||
// and the line as exception parameters to make them easy to
|
exception_record.NumberParameters = 3;
|
||||||
// access by the developer on the far side.
|
exception_record.ExceptionInformation[0] =
|
||||||
exception_record.NumberParameters = 3;
|
reinterpret_cast<ULONG_PTR>(&assertion.expression);
|
||||||
exception_record.ExceptionInformation[0] =
|
exception_record.ExceptionInformation[1] =
|
||||||
reinterpret_cast<ULONG_PTR>(&assertion.expression);
|
reinterpret_cast<ULONG_PTR>(&assertion.file);
|
||||||
exception_record.ExceptionInformation[1] =
|
exception_record.ExceptionInformation[2] = assertion.line;
|
||||||
reinterpret_cast<ULONG_PTR>(&assertion.file);
|
|
||||||
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
|
||||||
|
@ -526,10 +516,10 @@ void ExceptionHandler::HandleInvalidParameter(const wchar_t* expression,
|
||||||
if (current_handler->IsOutOfProcess()) {
|
if (current_handler->IsOutOfProcess()) {
|
||||||
success = current_handler->WriteMinidumpWithException(
|
success = current_handler->WriteMinidumpWithException(
|
||||||
GetCurrentThreadId(),
|
GetCurrentThreadId(),
|
||||||
exinfo,
|
&exception_ptrs,
|
||||||
&assertion);
|
&assertion);
|
||||||
} else {
|
} else {
|
||||||
success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
|
success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
|
||||||
&assertion);
|
&assertion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,27 +576,19 @@ void ExceptionHandler::HandlePureVirtualCall() {
|
||||||
CONTEXT exception_context = {};
|
CONTEXT exception_context = {};
|
||||||
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
|
EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context };
|
||||||
|
|
||||||
EXCEPTION_POINTERS* exinfo = NULL;
|
::RtlCaptureContext(&exception_context);
|
||||||
|
|
||||||
RtlCaptureContextPtr fnRtlCaptureContext = (RtlCaptureContextPtr)
|
exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
|
||||||
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
|
||||||
// We store pointers to the the expression and function strings,
|
// access by the developer on the far side.
|
||||||
// and the line as exception parameters to make them easy to
|
exception_record.NumberParameters = 3;
|
||||||
// access by the developer on the far side.
|
exception_record.ExceptionInformation[0] =
|
||||||
exception_record.NumberParameters = 3;
|
reinterpret_cast<ULONG_PTR>(&assertion.expression);
|
||||||
exception_record.ExceptionInformation[0] =
|
exception_record.ExceptionInformation[1] =
|
||||||
reinterpret_cast<ULONG_PTR>(&assertion.expression);
|
reinterpret_cast<ULONG_PTR>(&assertion.file);
|
||||||
exception_record.ExceptionInformation[1] =
|
exception_record.ExceptionInformation[2] = assertion.line;
|
||||||
reinterpret_cast<ULONG_PTR>(&assertion.file);
|
|
||||||
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
|
||||||
|
@ -615,10 +597,10 @@ void ExceptionHandler::HandlePureVirtualCall() {
|
||||||
if (current_handler->IsOutOfProcess()) {
|
if (current_handler->IsOutOfProcess()) {
|
||||||
success = current_handler->WriteMinidumpWithException(
|
success = current_handler->WriteMinidumpWithException(
|
||||||
GetCurrentThreadId(),
|
GetCurrentThreadId(),
|
||||||
exinfo,
|
&exception_ptrs,
|
||||||
&assertion);
|
&assertion);
|
||||||
} else {
|
} else {
|
||||||
success = current_handler->WriteMinidumpOnHandlerThread(exinfo,
|
success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs,
|
||||||
&assertion);
|
&assertion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +660,18 @@ bool ExceptionHandler::WriteMinidumpOnHandlerThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExceptionHandler::WriteMinidump() {
|
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) {
|
bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS* exinfo) {
|
||||||
|
|
Loading…
Reference in a new issue