[fuzzer] Add Windows Visual C++ exception intercept

Adds a new option, `handle_winexcept` to try to intercept uncaught
Visual C++ exceptions on Windows. On Linux, such exceptions are handled
implicitly by `std::terminate()` raising `SIBABRT`. This option brings the
Windows behavior in line with Linux.

Unfortunately this exception code is intentionally undocumented, however
has remained stable for the last decade. More information can be found
here: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273

Reviewed By: morehouse, metzman

Differential Revision: https://reviews.llvm.org/D89755

GitOrigin-RevId: f897e82bfd86099a5321e3fd50c63598e11e289b
diff --git a/FuzzerDriver.cpp b/FuzzerDriver.cpp
index 6b674c4..447cafc 100644
--- a/FuzzerDriver.cpp
+++ b/FuzzerDriver.cpp
@@ -829,6 +829,8 @@
   Options.HandleXfsz = Flags.handle_xfsz;
   Options.HandleUsr1 = Flags.handle_usr1;
   Options.HandleUsr2 = Flags.handle_usr2;
+  Options.HandleWinExcept = Flags.handle_winexcept;
+
   SetSignalHandler(Options);
 
   std::atexit(Fuzzer::StaticExitCallback);
diff --git a/FuzzerFlags.def b/FuzzerFlags.def
index ef6c3f8..ab31da0 100644
--- a/FuzzerFlags.def
+++ b/FuzzerFlags.def
@@ -145,6 +145,8 @@
 FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
 FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
 FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
+FUZZER_FLAG_INT(handle_winexcept, 1, "If 1, try to intercept uncaught Windows "
+    "Visual C++ Exceptions.")
 FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
     "if 2, close stderr; if 3, close both. "
     "Be careful, this will also close e.g. stderr of asan.")
diff --git a/FuzzerOptions.h b/FuzzerOptions.h
index 21155e9..d0c285a 100644
--- a/FuzzerOptions.h
+++ b/FuzzerOptions.h
@@ -84,6 +84,7 @@
   bool HandleXfsz = false;
   bool HandleUsr1 = false;
   bool HandleUsr2 = false;
+  bool HandleWinExcept = false;
 };
 
 }  // namespace fuzzer
diff --git a/FuzzerUtilWindows.cpp b/FuzzerUtilWindows.cpp
index a360b65..1a54bb5 100644
--- a/FuzzerUtilWindows.cpp
+++ b/FuzzerUtilWindows.cpp
@@ -60,7 +60,15 @@
       if (HandlerOpt->HandleFpe)
         Fuzzer::StaticCrashSignalCallback();
       break;
-    // TODO: handle (Options.HandleXfsz)
+    // This is an undocumented exception code corresponding to a Visual C++
+    // Exception.
+    //
+    // See: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273
+    case 0xE06D7363:
+      if (HandlerOpt->HandleWinExcept)
+        Fuzzer::StaticCrashSignalCallback();
+      break;
+      // TODO: Handle (Options.HandleXfsz)
   }
   return EXCEPTION_CONTINUE_SEARCH;
 }
@@ -127,7 +135,7 @@
     }
 
   if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
-      Options.HandleFpe)
+      Options.HandleFpe || Options.HandleWinExcept)
     SetUnhandledExceptionFilter(ExceptionHandler);
 
   if (Options.HandleAbrt)