From b4fd512c36ca344a3ff69350219e8b0a67e9472a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= 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 --- llvm/include/llvm/Support/Process.h | 4 ++++ llvm/lib/Support/Process.cpp | 2 +- llvm/lib/Support/Unix/Process.inc | 3 +++ llvm/lib/Support/Windows/Process.inc | 6 ++++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/Process.h b/llvm/include/llvm/Support/Process.h index 729917bb41f4aa..6687e5e7ff9a66 100644 --- a/llvm/include/llvm/Support/Process.h +++ b/llvm/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/llvm/lib/Support/Process.cpp b/llvm/lib/Support/Process.cpp index e0814444876ce4..e7e9a8b56f7420 100644 --- a/llvm/lib/Support/Process.cpp +++ b/llvm/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/llvm/lib/Support/Unix/Process.inc b/llvm/lib/Support/Unix/Process.inc index 1ea36aae63f242..30b957e6a1c4fb 100644 --- a/llvm/lib/Support/Unix/Process.inc +++ b/llvm/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/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc index 910d2395d2772d..c0e97815167dd6 100644 --- a/llvm/lib/Support/Windows/Process.inc +++ b/llvm/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"); +}