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
diff --git a/chrome_frame/exception_barrier.cc b/chrome_frame/exception_barrier.cc
index 51e764a..6fb54801 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 @@
                         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);
     }
   }