aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Process.cpp
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2020-11-12 08:14:20 -0500
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2020-11-12 08:14:43 -0500
commit45b8a741fbbf271e0fb71294cb7cdce3ad4b9bf3 (patch)
tree36f232547cfcc617e32d65736908a71758094d14 /llvm/lib/Support/Process.cpp
parentf37834c7dcbe69405bf3e182d2b3e3227cc4a569 (diff)
downloadllvm-45b8a741fbbf271e0fb71294cb7cdce3ad4b9bf3.zip
llvm-45b8a741fbbf271e0fb71294cb7cdce3ad4b9bf3.tar.gz
llvm-45b8a741fbbf271e0fb71294cb7cdce3ad4b9bf3.tar.bz2
[LLD][COFF] When using LLD-as-a-library, always prevent re-entrance on failures
This is a follow-up for D70378 (Cover usage of LLD as a library). While debugging an intermittent failure on a bot, I recalled this scenario which causes the issue: 1.When executing lld/test/ELF/invalid/symtab-sh-info.s L45, we reach lld::elf::Obj-File::ObjFile() which goes straight into its base ELFFileBase(), then ELFFileBase::init(). 2.At that point fatal() is thrown in lld/ELF/InputFiles.cpp L381, leaving a half-initialized ObjFile instance. 3.We then end up in lld::exitLld() and since we are running with LLD_IN_TEST, we hapily restore the control flow to CrashRecoveryContext::RunSafely() then back in lld::safeLldMain(). 4.Before this patch, we called errorHandler().reset() just after, and this attempted to reset the associated SpecificAlloc<ObjFile<ELF64LE>>. That tried to free the half-initialized ObjFile instance, and more precisely its ObjFile::dwarf member. Sometimes that worked, sometimes it failed and was catched by the CrashRecoveryContext. This scenario was the reason we called errorHandler().reset() through a CrashRecoveryContext. But in some rare cases, the above repro somehow corrupted the heap, creating a stack overflow. When the CrashRecoveryContext's filter (that is, __except (ExceptionFilter(GetExceptionInformation()))) tried to handle the exception, it crashed again since the stack was exhausted -- and that took the whole application down. That is the issue seen on the bot. Locally it happens about 1 times out of 15. Now this situation can happen anywhere in LLD. Since catching stack overflows is not a reliable scenario ATM when using CrashRecoveryContext, we're now preventing further re-entrance when such failures occur, by signaling lld::SafeReturn::canRunAgain=false. When running with LLD_IN_TEST=2 (or above), only one iteration will be executed, instead of two. Differential Revision: https://reviews.llvm.org/D88348
Diffstat (limited to 'llvm/lib/Support/Process.cpp')
-rw-r--r--llvm/lib/Support/Process.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/llvm/lib/Support/Process.cpp b/llvm/lib/Support/Process.cpp
index 9f0b689..8626117 100644
--- a/llvm/lib/Support/Process.cpp
+++ b/llvm/lib/Support/Process.cpp
@@ -20,6 +20,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
+#include <stddef.h> // for _Exit
+
using namespace llvm;
using namespace sys;
@@ -91,10 +93,14 @@ static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS;
bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; }
LLVM_ATTRIBUTE_NORETURN
-void Process::Exit(int RetCode) {
+void Process::Exit(int RetCode, bool NoCleanup) {
if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
CRC->HandleExit(RetCode);
- ::exit(RetCode);
+
+ if (NoCleanup)
+ _Exit(RetCode);
+ else
+ ::exit(RetCode);
}
// Include the platform-specific parts of this class.