From b4fd512c36ca344a3ff69350219e8b0a67e9472a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Fri, 21 May 2021 23:50:01 +0300
Subject: [PATCH] [Windows] Use TerminateProcess to exit without running
 destructors

If exiting using _Exit or ExitProcess, DLLs are still unloaded
cleanly before exiting, running destructors and other cleanup in those
DLLs. When the caller expects to exit without cleanup, running
destructors in some loaded DLLs (which can be either libLLVM.dll or
e.g. libc++.dll) can cause deadlocks occasionally.

This is an alternative to D102684.

Differential Revision: https://reviews.llvm.org/D102944
---
 include/llvm/Support/Process.h  | 4 ++++
 lib/Support/Process.cpp         | 2 +-
 lib/Support/Unix/Process.inc    | 3 +++
 lib/Support/Windows/Process.inc | 6 ++++++
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 729917bb41f4a..6687e5e7ff9a6 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -216,6 +216,10 @@ class Process {
   /// Use \arg NoCleanup for calling _exit() instead of exit().
   LLVM_ATTRIBUTE_NORETURN
   static void Exit(int RetCode, bool NoCleanup = false);
+
+private:
+  LLVM_ATTRIBUTE_NORETURN
+  static void ExitNoCleanup(int RetCode);
 };
 
 }
diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp
index e0814444876ce..e7e9a8b56f742 100644
--- a/lib/Support/Process.cpp
+++ b/lib/Support/Process.cpp
@@ -98,7 +98,7 @@ void Process::Exit(int RetCode, bool NoCleanup) {
     CRC->HandleExit(RetCode);
 
   if (NoCleanup)
-    _Exit(RetCode);
+    ExitNoCleanup(RetCode);
   else
     ::exit(RetCode);
 }
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index 1ea36aae63f24..30b957e6a1c4f 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -460,3 +460,6 @@ unsigned llvm::sys::Process::GetRandomNumber() {
   return ::rand();
 #endif
 }
+
+LLVM_ATTRIBUTE_NORETURN
+void Process::ExitNoCleanup(int RetCode) { _Exit(RetCode); }
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index 910d2395d2772..c0e97815167dd 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -503,3 +503,9 @@ bool llvm::RunningWindows8OrGreater() {
   // Windows 8 is version 6.2, service pack 0.
   return GetWindowsOSVersion() >= llvm::VersionTuple(6, 2, 0, 0);
 }
+
+LLVM_ATTRIBUTE_NORETURN
+void Process::ExitNoCleanup(int RetCode) {
+  TerminateProcess(GetCurrentProcess(), RetCode);
+  llvm_unreachable("TerminateProcess doesn't return");
+}
