[compiler-rt] [orc][mach-o] Unlock the JITDylib state mutex during +load (PR #105333)
Ben Langmuir via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 20 13:18:11 PDT 2024
https://github.com/benlangmuir created https://github.com/llvm/llvm-project/pull/105333
Similar to what was already done for static initializers, we need to unlock the state mutext when calling out to libobjc to run +load methods in case they cause us to reenter the runtime, which was previously deadlocking. No test for now, because we don't have any code paths in llvm-jitlink itself that could lead to this deadlock. If we interpose calls to dlopen to go back to the JIT in the future then calling dlopen from a +load is the easiest way to reproduce this.
rdar://133430490
>From 0d75abba98bb796bcd514c1d6d26c71c27d0c76f Mon Sep 17 00:00:00 2001
From: Ben Langmuir <blangmuir at apple.com>
Date: Tue, 20 Aug 2024 11:34:04 -0700
Subject: [PATCH] [orc][mach-o] Unlock the JITDylib state mutex during +load
Similar to what was already done for static initializers, we need to
unlock the state mutext when calling out to libobjc to run +load methods
in case they cause us to reenter the runtime, which was previously
deadlocking. No test for now, because we don't have any code paths in
llvm-jitlink itself that could lead to this deadlock. If we interpose
calls to dlopen to go back to the JIT in the future then calling dlopen
from a +load is the easiest way to reproduce this.
rdar://133430490
---
compiler-rt/lib/orc/macho_platform.cpp | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index 340846f5f9001..9b4f6e5fd417c 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -367,7 +367,9 @@ class MachOPlatformRuntimeState {
static Error registerEHFrames(span<const char> EHFrameSection);
static Error deregisterEHFrames(span<const char> EHFrameSection);
- static Error registerObjCRegistrationObjects(JITDylibState &JDS);
+ static Error
+ registerObjCRegistrationObjects(std::unique_lock<std::mutex> &JDStatesLock,
+ JITDylibState &JDS);
static Error runModInits(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS);
@@ -1059,7 +1061,7 @@ Error MachOPlatformRuntimeState::deregisterEHFrames(
}
Error MachOPlatformRuntimeState::registerObjCRegistrationObjects(
- JITDylibState &JDS) {
+ std::unique_lock<std::mutex> &JDStatesLock, JITDylibState &JDS) {
ORC_RT_DEBUG(printdbg("Registering Objective-C / Swift metadata.\n"));
std::vector<char *> RegObjBases;
@@ -1074,6 +1076,9 @@ Error MachOPlatformRuntimeState::registerObjCRegistrationObjects(
"Could not register Objective-C / Swift metadata: _objc_map_images / "
"_objc_load_image not found");
+ // Release the lock while calling out to libobjc in case +load methods cause
+ // reentering the orc runtime.
+ JDStatesLock.unlock();
std::vector<char *> Paths;
Paths.resize(RegObjBases.size());
_objc_map_images(RegObjBases.size(), Paths.data(),
@@ -1081,6 +1086,7 @@ Error MachOPlatformRuntimeState::registerObjCRegistrationObjects(
for (void *RegObjBase : RegObjBases)
_objc_load_image(nullptr, reinterpret_cast<mach_header *>(RegObjBase));
+ JDStatesLock.lock();
return Error::success();
}
@@ -1218,7 +1224,7 @@ Error MachOPlatformRuntimeState::dlopenInitialize(
}
// Initialize this JITDylib.
- if (auto Err = registerObjCRegistrationObjects(JDS))
+ if (auto Err = registerObjCRegistrationObjects(JDStatesLock, JDS))
return Err;
if (auto Err = runModInits(JDStatesLock, JDS))
return Err;
More information about the llvm-commits
mailing list