From 5951dd28afc3adb82ee21926c7f6cf46f9f15b87 Mon Sep 17 00:00:00 2001 From: "mark@chromium.org" Date: Wed, 21 Dec 2011 22:09:56 +0000 Subject: 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 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@897 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/client/windows/handler/exception_handler.cc | 83 +++++++++++-------------- 1 file changed, 38 insertions(+), 45 deletions(-) (limited to 'src/client/windows/handler/exception_handler.cc') 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(&assertion.expression); - exception_record.ExceptionInformation[1] = - reinterpret_cast(&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(&assertion.expression); + exception_record.ExceptionInformation[1] = + reinterpret_cast(&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(&assertion.expression); - exception_record.ExceptionInformation[1] = - reinterpret_cast(&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(&assertion.expression); + exception_record.ExceptionInformation[1] = + reinterpret_cast(&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) { -- cgit v1.2.1