diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-01 02:10:06 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-01 02:10:06 +0000 |
commit | 72354315dd3c9682370ee2eea62446b7e5539990 (patch) | |
tree | 4f8be23e6d8ec76c7d537ca693815a7405cf2f02 | |
parent | c96c3c973c12f552ed6abd565fd326c32c227a5f (diff) | |
download | chromium_src-72354315dd3c9682370ee2eea62446b7e5539990.zip chromium_src-72354315dd3c9682370ee2eea62446b7e5539990.tar.gz chromium_src-72354315dd3c9682370ee2eea62446b7e5539990.tar.bz2 |
Avoid reporting crashes for exceptions that hit our SEH from calls to the original implementation of BindToStorage() when we do not wrap the bind status callback.
BUG=42660
TEST=Induce exception in code called under original IMoniker::BindToStorage implementation when we don't wrap the callback and notice that no crash is reported.
Review URL: http://codereview.chromium.org/1748016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46176 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/chrome_frame_reporting.cc | 12 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/crash_report.cc | 39 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/vectored_handler-impl.h | 42 | ||||
-rw-r--r-- | chrome_frame/exception_barrier.cc | 64 | ||||
-rw-r--r-- | chrome_frame/exception_barrier.h | 234 | ||||
-rw-r--r-- | chrome_frame/exception_barrier_lowlevel.asm | 8 | ||||
-rw-r--r-- | chrome_frame/test/exception_barrier_unittest.cc | 35 | ||||
-rw-r--r-- | chrome_frame/urlmon_moniker.cc | 9 |
8 files changed, 301 insertions, 142 deletions
diff --git a/chrome_frame/chrome_frame_reporting.cc b/chrome_frame/chrome_frame_reporting.cc index 556747b2..807599c8 100644 --- a/chrome_frame/chrome_frame_reporting.cc +++ b/chrome_frame/chrome_frame_reporting.cc @@ -46,11 +46,6 @@ google_breakpad::CustomClientInfo* GetCustomInfo(const wchar_t* dll_path) { return &custom_info; } - -void CALLBACK BreakpadHandler(EXCEPTION_POINTERS *ptrs) { - WriteMinidumpForException(ptrs); -} - extern "C" IMAGE_DOS_HEADER __ImageBase; bool InitializeCrashReporting() { @@ -61,9 +56,9 @@ bool InitializeCrashReporting() { if (!always_take_dump && !GoogleUpdateSettings::GetCollectStatsConsent()) return true; - // Set the handler for ExceptionBarrier for this module: - DCHECK(ExceptionBarrier::handler() == NULL); - ExceptionBarrier::set_handler(BreakpadHandler); + // If we got here, we want to report crashes, so make sure all + // ExceptionBarrierBase instances do so. + ExceptionBarrierConfig::set_enabled(true); // Get the alternate dump directory. We use the temp path. FilePath temp_directory; @@ -97,5 +92,6 @@ bool InitializeCrashReporting() { } bool ShutdownCrashReporting() { + ExceptionBarrierConfig::set_enabled(false); return ShutdownVectoredCrashReporting(); } diff --git a/chrome_frame/crash_reporting/crash_report.cc b/chrome_frame/crash_reporting/crash_report.cc index cfb4e95..4589bab 100644 --- a/chrome_frame/crash_reporting/crash_report.cc +++ b/chrome_frame/crash_reporting/crash_report.cc @@ -47,36 +47,6 @@ static void veh_segment_end() {} #pragma code_seg(push, ".text$vm") #include "chrome_frame/crash_reporting/vectored_handler-impl.h" -// Use Win32 API; use breakpad for dumps; checks for single (current) module. -class CrashHandlerTraits : public Win32VEHTraits, - public ModuleOfInterestWithExcludedRegion { - public: - CrashHandlerTraits() {} - - // Note that breakpad_lock must be held when this is called. - void Init(google_breakpad::ExceptionHandler* breakpad, Lock* breakpad_lock) { - DCHECK(breakpad); - DCHECK(breakpad_lock); - breakpad_lock->AssertAcquired(); - - Win32VEHTraits::InitializeIgnoredBlocks(); - ModuleOfInterestWithExcludedRegion::SetCurrentModule(); - // Pointers to static (non-extern) functions take the address of the - // function's first byte, as opposed to an entry in the compiler generated - // JMP table. In release builds /OPT:REF wipes away the JMP table, but debug - // builds are not so lucky. - ModuleOfInterestWithExcludedRegion::SetExcludedRegion(&veh_segment_start, - &veh_segment_end); - } - - void Shutdown() { - } - - inline bool WriteDump(EXCEPTION_POINTERS* p) { - return WriteMinidumpForException(p); - } -}; - class CrashHandler { public: CrashHandler() : veh_id_(NULL), handler_(&crash_api_) {} @@ -115,14 +85,17 @@ bool CrashHandler::Init(google_breakpad::ExceptionHandler* breakpad, if (veh_id_) return true; + crash_api_.Init(&veh_segment_start, &veh_segment_end, + &WriteMinidumpForException); + void* id = ::AddVectoredExceptionHandler(FALSE, &VectoredHandlerEntryPoint); if (id != NULL) { veh_id_ = id; - crash_api_.Init(breakpad, breakpad_lock); return true; + } else { + crash_api_.Shutdown(); + return false; } - - return false; } void CrashHandler::Shutdown() { diff --git a/chrome_frame/crash_reporting/vectored_handler-impl.h b/chrome_frame/crash_reporting/vectored_handler-impl.h index 641522f..175e496 100644 --- a/chrome_frame/crash_reporting/vectored_handler-impl.h +++ b/chrome_frame/crash_reporting/vectored_handler-impl.h @@ -4,6 +4,8 @@ #ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ #define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ + +#include "base/logging.h" #include "chrome_frame/crash_reporting/vectored_handler.h" #include "chrome_frame/crash_reporting/nt_loader.h" @@ -262,4 +264,44 @@ Win32VEHTraits::IgnoreExceptions[kIgnoreEntries] = { { "kernel32.dll", "IsBadStringPtrW", 0, 100, NULL }, }; +// Use Win32 API; checks for single (current) module. Will call a specified +// CrashHandlerTraits::DumpHandler when taking a dump. +class CrashHandlerTraits : public Win32VEHTraits, + public ModuleOfInterestWithExcludedRegion { + public: + + typedef bool (*DumpHandler)(EXCEPTION_POINTERS* p); + + CrashHandlerTraits() : dump_handler_(NULL) {} + + // Note that breakpad_lock must be held when this is called. + void Init(const void* veh_segment_start, const void* veh_segment_end, + DumpHandler dump_handler) { + DCHECK(dump_handler); + dump_handler_ = dump_handler; + Win32VEHTraits::InitializeIgnoredBlocks(); + ModuleOfInterestWithExcludedRegion::SetCurrentModule(); + // Pointers to static (non-extern) functions take the address of the + // function's first byte, as opposed to an entry in the compiler generated + // JMP table. In release builds /OPT:REF wipes away the JMP table, but debug + // builds are not so lucky. + ModuleOfInterestWithExcludedRegion::SetExcludedRegion(veh_segment_start, + veh_segment_end); + } + + void Shutdown() { + } + + inline bool WriteDump(EXCEPTION_POINTERS* p) { + if (dump_handler_) { + return dump_handler_(p); + } else { + return false; + } + } + + private: + DumpHandler dump_handler_; +}; + #endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ diff --git a/chrome_frame/exception_barrier.cc b/chrome_frame/exception_barrier.cc index 51e764a..6fb5480 100644 --- a/chrome_frame/exception_barrier.cc +++ b/chrome_frame/exception_barrier.cc @@ -6,12 +6,18 @@ // get crash reports of exceptions that pass over same. #include "chrome_frame/exception_barrier.h" +#include "chrome_frame/crash_reporting/vectored_handler-impl.h" +#include "chrome_frame/crash_reporting/crash_report.h" + enum { // Flag set by exception handling machinery when unwinding EH_UNWINDING = 0x00000002 }; -ExceptionBarrier::ExceptionHandler ExceptionBarrier::s_handler_ = NULL; +bool ExceptionBarrierConfig::s_enabled_ = false; + +ExceptionBarrierCustomHandler::CustomExceptionHandler + ExceptionBarrierCustomHandler::s_custom_handler_ = NULL; // This function must be extern "C" to match up with the SAFESEH // declaration in our corresponding ASM file @@ -20,19 +26,53 @@ ExceptionBarrierHandler(struct _EXCEPTION_RECORD* exception_record, void* establisher_frame, struct _CONTEXT* context, void* reserved) { - establisher_frame; // unreferenced formal parameter - reserved; - if (!(exception_record->ExceptionFlags & EH_UNWINDING)) { - // When the exception is really propagating through us, we'd like to be - // called before the state of the program has been modified by the stack - // unwinding. In the absence of an exception handler, the unhandled - // exception filter gets called between the first chance and the second - // chance exceptions, so Windows pops either the JIT debugger or WER UI. - // This is not desirable in most of the cases. - ExceptionBarrier::ExceptionHandler handler = ExceptionBarrier::handler(); + // When the exception is really propagating through us, we'd like to be + // called before the state of the program has been modified by the stack + // unwinding. In the absence of an exception handler, the unhandled + // exception filter gets called between the first chance and the second + // chance exceptions, so Windows pops either the JIT debugger or WER UI. + // This is not desirable in most of the cases. + EXCEPTION_POINTERS ptrs = { exception_record, context }; + + if (ExceptionBarrierConfig::enabled() && + IS_DISPATCHING(exception_record->ExceptionFlags)) { + WriteMinidumpForException(&ptrs); + } + + return ExceptionContinueSearch; +} + +extern "C" EXCEPTION_DISPOSITION __cdecl +ExceptionBarrierReportOnlyModuleHandler( + struct _EXCEPTION_RECORD* exception_record, + void* establisher_frame, + struct _CONTEXT* context, + void* reserved) { + EXCEPTION_POINTERS ptrs = { exception_record, context }; + + if (ExceptionBarrierConfig::enabled() && + IS_DISPATCHING(exception_record->ExceptionFlags)) { + CrashHandlerTraits traits; + traits.Init(0, 0, &WriteMinidumpForException); + if (traits.IsOurModule(exception_record->ExceptionAddress)) { + traits.WriteDump(&ptrs); + } + } + + return ExceptionContinueSearch; +} + +extern "C" EXCEPTION_DISPOSITION __cdecl +ExceptionBarrierCallCustomHandler(struct _EXCEPTION_RECORD* exception_record, + void* establisher_frame, + struct _CONTEXT* context, + void* reserved) { + if (ExceptionBarrierConfig::enabled() && + IS_DISPATCHING(exception_record->ExceptionFlags)) { + ExceptionBarrierCustomHandler::CustomExceptionHandler handler = + ExceptionBarrierCustomHandler::custom_handler(); if (handler) { EXCEPTION_POINTERS ptrs = { exception_record, context }; - handler(&ptrs); } } diff --git a/chrome_frame/exception_barrier.h b/chrome_frame/exception_barrier.h index 26cbc44..e3e5350 100644 --- a/chrome_frame/exception_barrier.h +++ b/chrome_frame/exception_barrier.h @@ -1,96 +1,196 @@ // Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - +// // A class to make it easy to tag exception propagation boundaries and // get crash reports of exceptions that pass over same. +// +// An exception barrier is used to report exceptions that pass through +// a boundary where exceptions shouldn't pass, such as e.g. COM interface +// boundaries. +// This is handy for any kind of plugin code, where if the exception passes +// through unhindered, it'll either be swallowed by an SEH exception handler +// above us on the stack, or be reported as an unhandled exception for +// the application hosting the plugin code. +// +// IMPORTANT NOTE: This class has crash_reporting disabled by default. To +// enable crash reporting call: +// +// @code +// ExceptionBarrierBase::set_crash_handling(true) +// @endcode +// +// somewhere in your initialization code. +// +// Then, to use this class, simply instantiate an ExceptionBarrier just inside +// the code boundary, like this: +// @code +// HRESULT SomeObject::SomeCOMMethod(...) { +// ExceptionBarrier report_crashes; +// +// ... other code here ... +// } +// @endcode +// +// There are three ExceptionBarrier types defined here: +// 1) ExceptionBarrier which reports all crashes it sees. +// 2) ExceptionBarrierReportOnlyModule which reports only crashes occurring +// in this module. +// 3) ExceptionBarrierCustomHandler which calls the handler set by a call +// to ExceptionBarrierCallCustomHandler::set_custom_handler(). Note that +// there is one custom handler for all ExceptionBarrierCallCustomHandler +// instances. If set_custom_handler() is never called, this places an +// SEH in the chain that just returns ExceptionContinueSearch. + #ifndef CHROME_FRAME_EXCEPTION_BARRIER_H_ #define CHROME_FRAME_EXCEPTION_BARRIER_H_ #include <windows.h> -/// This is the type dictated for an exception handler by the platform ABI -/// @see _except_handler in excpt.h -typedef EXCEPTION_DISPOSITION (__cdecl *ExceptionHandlerFunc)( - struct _EXCEPTION_RECORD *exception_record, - void * establisher_frame, - struct _CONTEXT *context, - void * reserved); +extern "C" IMAGE_DOS_HEADER __ImageBase; -/// The type of an exception record in the exception handler chain +// This is the type dictated for an exception handler by the platform ABI +// @see _except_handler in excpt.h +typedef EXCEPTION_DISPOSITION (__cdecl* ExceptionHandlerFunc)( + struct _EXCEPTION_RECORD* exception_record, + void* establisher_frame, + struct _CONTEXT* context, + void* reserved); + +// The type of an exception record in the exception handler chain struct EXCEPTION_REGISTRATION { - EXCEPTION_REGISTRATION *prev; + EXCEPTION_REGISTRATION* prev; ExceptionHandlerFunc handler; }; -/// This is our raw exception handler, it must be declared extern "C" to -/// match up with the SAFESEH declaration in our corresponding ASM file +// This is our raw exception handler, it must be declared extern "C" to +// match up with the SAFESEH declaration in our corresponding ASM file. +extern "C" EXCEPTION_DISPOSITION __cdecl +ExceptionBarrierHandler(struct _EXCEPTION_RECORD* exception_record, + void* establisher_frame, + struct _CONTEXT* context, + void* reserved); + +// An alternate raw exception handler that reports crashes only for the current +// module. It must be declared extern "C" to match up with the SAFESEH +// declaration in our corresponding ASM file. extern "C" EXCEPTION_DISPOSITION __cdecl -ExceptionBarrierHandler(struct _EXCEPTION_RECORD *exception_record, - void * establisher_frame, - struct _CONTEXT *context, - void * reserved); - -/// An exception barrier is used to report exceptions that pass through -/// a boundary where exceptions shouldn't pass, such as e.g. COM interface -/// boundaries. -/// This is handy for any kind of plugin code, where if the exception passes -/// through unhindered, it'll either be swallowed by an SEH exception handler -/// above us on the stack, or be reported as an unhandled exception for -/// the application hosting the plugin code. -/// -/// To use this class, simply instantiate an ExceptionBarrier just inside -/// the code boundary, like this: -/// @code -/// HRESULT SomeObject::SomeCOMMethod(...) { -/// ExceptionBarrier report_crashes; -/// -/// ... other code here ... -/// } -/// @endcode -class ExceptionBarrier { +ExceptionBarrierReportOnlyModuleHandler( + struct _EXCEPTION_RECORD* exception_record, + void* establisher_frame, + struct _CONTEXT* context, + void* reserved); + +// An alternate raw exception handler that calls out to a custom handler. +// It must be declared extern "C" to match up with the SAFESEH declaration in +// our corresponding ASM file. +extern "C" EXCEPTION_DISPOSITION __cdecl +ExceptionBarrierCallCustomHandler( + struct _EXCEPTION_RECORD* exception_record, + void* establisher_frame, + struct _CONTEXT* context, + void* reserved); + + +// @name These are implemented in the associated .asm file +// @{ +extern "C" void WINAPI RegisterExceptionRecord( + EXCEPTION_REGISTRATION* registration, + ExceptionHandlerFunc func); +extern "C" void WINAPI UnregisterExceptionRecord( + EXCEPTION_REGISTRATION* registration); +// @} + + +// Traits classes for ExceptionBarrierT. +class EBTraitsBase { public: - /// Register the barrier in the SEH chain - ExceptionBarrier(); + static void UnregisterException(EXCEPTION_REGISTRATION* registration) { + UnregisterExceptionRecord(registration); + } +}; - /// And unregister on destruction - ~ExceptionBarrier(); +class EBReportAllTraits : public EBTraitsBase { + public: + static void RegisterException(EXCEPTION_REGISTRATION* registration) { + RegisterExceptionRecord(registration, ExceptionBarrierHandler); + } +}; - /// Signature of the handler function which gets notified when - /// an exception propagates through a barrier. - typedef void (CALLBACK *ExceptionHandler)(EXCEPTION_POINTERS *ptrs); +class EBReportOnlyThisModuleTraits : public EBTraitsBase { + public: + static void RegisterException(EXCEPTION_REGISTRATION* registration) { + RegisterExceptionRecord(registration, + ExceptionBarrierReportOnlyModuleHandler); + } +}; - /// @name Accessors - /// @{ - static void set_handler(ExceptionHandler handler) { s_handler_ = handler; } - static ExceptionHandler handler() { return s_handler_; } - /// @} +class EBCustomHandlerTraits : public EBTraitsBase { + public: + static void RegisterException(EXCEPTION_REGISTRATION* registration) { + RegisterExceptionRecord(registration, + ExceptionBarrierCallCustomHandler); + } +}; - private: - /// Our SEH frame - EXCEPTION_REGISTRATION registration_; +class ExceptionBarrierConfig { + public: + // Used to globally enable or disable crash handling by ExceptionBarrierBase + // instances. + static void set_enabled(bool enabled) { + s_enabled_ = enabled; + } + static bool enabled() { return s_enabled_; } + + // Whether crash reports are enabled. + static bool s_enabled_; +}; - /// The function that gets invoked if an exception - /// propagates through a barrier - static ExceptionHandler s_handler_; +template <typename RegistrarTraits> +class ExceptionBarrierT { + public: + // Register the barrier in the SEH chain + ExceptionBarrierT() { + RegistrarTraits::RegisterException(®istration_); + } + + // Unregister on destruction + virtual ~ExceptionBarrierT() { + RegistrarTraits::UnregisterException(®istration_); + } + + protected: + // Our SEH frame + EXCEPTION_REGISTRATION registration_; }; -/// @name These are implemented in the associated .asm file -/// @{ -extern "C" void WINAPI RegisterExceptionRecord( - EXCEPTION_REGISTRATION *registration, - ExceptionHandlerFunc func); -extern "C" void WINAPI UnregisterExceptionRecord( - EXCEPTION_REGISTRATION *registration); -/// @} +// This class allows for setting a custom exception handler function. The +// handler is shared among all instances. This class is intended to enable +// testing of the SEH registration. +template <typename RegistrarTraits> +class ExceptionBarrierCustomHandlerT : + public ExceptionBarrierT<typename RegistrarTraits> { + public: + // Signature of the handler function which gets notified when + // an exception propagates through a barrier. + typedef void (CALLBACK* CustomExceptionHandler)(EXCEPTION_POINTERS* ptrs); + // Used to set a global custom handler used by all + // ExceptionBarrierCustomHandler instances. + static void set_custom_handler(CustomExceptionHandler handler) { + s_custom_handler_ = handler; + } + static CustomExceptionHandler custom_handler() { return s_custom_handler_; } -inline ExceptionBarrier::ExceptionBarrier() { - RegisterExceptionRecord(®istration_, ExceptionBarrierHandler); -} + private: + static CustomExceptionHandler s_custom_handler_; +}; -inline ExceptionBarrier::~ExceptionBarrier() { - UnregisterExceptionRecord(®istration_); -} +// Convenience typedefs for the ExceptionBarrierT specializations. +typedef ExceptionBarrierT<EBReportAllTraits> ExceptionBarrier; +typedef ExceptionBarrierT<EBReportOnlyThisModuleTraits> + ExceptionBarrierReportOnlyModule; +typedef ExceptionBarrierCustomHandlerT<EBCustomHandlerTraits> + ExceptionBarrierCustomHandler; #endif // CHROME_FRAME_EXCEPTION_BARRIER_H_ diff --git a/chrome_frame/exception_barrier_lowlevel.asm b/chrome_frame/exception_barrier_lowlevel.asm index b759990..f8f652f 100644 --- a/chrome_frame/exception_barrier_lowlevel.asm +++ b/chrome_frame/exception_barrier_lowlevel.asm @@ -10,9 +10,17 @@ IF @version LT 800 _ExceptionBarrierHandler PROTO .SAFESEH _ExceptionBarrierHandler +_ExceptionBarrierReportOnlyModuleHandler PROTO +.SAFESEH _ExceptionBarrierReportOnlyModuleHandler +_ExceptionBarrierCallCustomHandler PROTO +.SAFESEH _ExceptionBarrierCallCustomHandler ELSE ExceptionBarrierHandler PROTO .SAFESEH ExceptionBarrierHandler +ExceptionBarrierReportOnlyModuleHandler PROTO +.SAFESEH ExceptionBarrierReportOnlyModuleHandler +ExceptionBarrierCallCustomHandler PROTO +.SAFESEH ExceptionBarrierCallCustomHandler ENDIF .586 diff --git a/chrome_frame/test/exception_barrier_unittest.cc b/chrome_frame/test/exception_barrier_unittest.cc index c31d878..eeffd2a 100644 --- a/chrome_frame/test/exception_barrier_unittest.cc +++ b/chrome_frame/test/exception_barrier_unittest.cc @@ -75,7 +75,7 @@ void AccessViolationCrash() { // A simple crash over the exception barrier void CrashOverExceptionBarrier() { - ExceptionBarrier barrier; + ExceptionBarrierCustomHandler barrier; TestSEHChainSane(); @@ -85,15 +85,15 @@ void CrashOverExceptionBarrier() { } #pragma warning(push) - // Inline asm assigning to 'FS:0' : handler not registered as safe handler - // This warning is in error (the compiler can't know that we register the - // handler as a safe SEH handler in an .asm file) - #pragma warning(disable:4733) -// Hand-generate an SEH frame implicating the ExceptionBarrierHandler, +// Inline asm assigning to 'FS:0' : handler not registered as safe handler +// This warning is in error (the compiler can't know that we register the +// handler as a safe SEH handler in an .asm file) +#pragma warning(disable:4733) +// Hand-generate an SEH frame implicating the ExceptionBarrierCallCustomHandler, // then crash to invoke it. __declspec(naked) void CrashOnManualSEHBarrierHandler() { __asm { - push ExceptionBarrierHandler + push ExceptionBarrierCallCustomHandler push FS:0 mov FS:0, esp call AccessViolationCrash @@ -102,43 +102,40 @@ __declspec(naked) void CrashOnManualSEHBarrierHandler() { } #pragma warning(pop) + class ExceptionBarrierTest: public testing::Test { -public: - ExceptionBarrierTest() : old_handler_(NULL) { + public: + ExceptionBarrierTest() { } // Install an exception handler for the ExceptionBarrier, and // set the handled flag to false. This allows us to see whether // the ExceptionBarrier gets to handle the exception virtual void SetUp() { - old_handler_ = ExceptionBarrier::handler(); - ExceptionBarrier::set_handler(ExceptionHandler); + ExceptionBarrierConfig::set_enabled(true); + ExceptionBarrierCustomHandler::set_custom_handler(&ExceptionHandler); s_handled_ = false; TestSEHChainSane(); } virtual void TearDown() { - ExceptionBarrier::set_handler(old_handler_); - TestSEHChainSane(); + ExceptionBarrierCustomHandler::set_custom_handler(NULL); + ExceptionBarrierConfig::set_enabled(false); } // The exception notification callback, sets the handled flag. static void CALLBACK ExceptionHandler(EXCEPTION_POINTERS* ptrs) { TestSEHChainSane(); - s_handled_ = true; } - // Old handler to restore on TearDown - ExceptionBarrier::ExceptionHandler old_handler_; - // Flag is set by handler static bool s_handled_; }; -bool ExceptionBarrierTest::s_handled_; +bool ExceptionBarrierTest::s_handled_ = false; bool TestExceptionExceptionBarrierHandler() { TestSEHChainSane(); @@ -271,7 +268,7 @@ bool TestRegularChaining(EXCEPTION_REGISTRATION* top) { } void RecurseAndCrashOverBarrier(int depth, bool crash) { - ExceptionBarrier barrier; + ExceptionBarrierCustomHandler barrier; if (0 == depth) { if (crash) diff --git a/chrome_frame/urlmon_moniker.cc b/chrome_frame/urlmon_moniker.cc index 4150927..cc9d6a8 100644 --- a/chrome_frame/urlmon_moniker.cc +++ b/chrome_frame/urlmon_moniker.cc @@ -174,7 +174,7 @@ HRESULT MonikerPatch::BindToObject(IMoniker_BindToObject_Fn original, DLOG(INFO) << __FUNCTION__; DCHECK(to_left == NULL); - ExceptionBarrier barrier; + ExceptionBarrierReportOnlyModule barrier; HRESULT hr = S_OK; // Bind context is marked for switch when we sniff data in BSCBStorageBind @@ -217,11 +217,14 @@ HRESULT MonikerPatch::BindToStorage(IMoniker_BindToStorage_Fn original, hr = callback->Initialize(me, bind_ctx); DCHECK(SUCCEEDED(hr)); - // Call the original back under an exception barrier only if we should - // wrap the callback. + // Report all crashes in the exception handler if we wrap the callback. + // Note that this avoids having the VEH report a crash if an SEH earlier in + // the chain handles the exception. ExceptionBarrier barrier; hr = original(me, bind_ctx, to_left, iid, obj); } else { + // If we don't wrap, only report a crash if the crash is in our own module. + ExceptionBarrierReportOnlyModule barrier; hr = original(me, bind_ctx, to_left, iid, obj); } |