From c4ccf608c2380796d64db108eed3b24c1b0140ef Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Sun, 10 Jul 2022 10:25:20 +0200 Subject: [PATCH] ManagedStatic: remove from GDBRegistrationListener An earlier version of this change originally landed as part of e6f1f062457c928c18a88c612f39d9e168f65a85 (D129120), which caused a Fuchsia buildbot regression in ExecutionEngine tests. Careful review suggests that the issue was that in the earlier version, the destructor of the JITDebugLock was run before the destructor of GDBJITRegistrationListener. The new version of the change moves the lock to a member variable of the (singleton!) GDBJITRegistartionListener so that destructors are run in the right order. --- .../ExecutionEngine/GDBRegistrationListener.cpp | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp index 29a623e..f1eeee3 100644 --- a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp +++ b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp @@ -12,7 +12,6 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" #include @@ -91,11 +90,18 @@ typedef llvm::DenseMap /// object files that are in executable memory managed by the client of this /// class. class GDBJITRegistrationListener : public JITEventListener { + /// Lock used to serialize all jit registration events, since they + /// modify global variables. + /// + /// Only a single instance of GDBJITRegistrationListener is ever created, + /// and so the lock can be a member variable of that instance. This ensures + /// destructors are run in the correct order. + sys::Mutex JITDebugLock; + /// A map of in-memory object files that have been registered with the /// JIT interface. RegisteredObjectBufferMap ObjectBufferMap; -public: /// Instantiates the JIT service. GDBJITRegistrationListener() = default; @@ -103,6 +109,12 @@ public: /// internal resources. ~GDBJITRegistrationListener() override; +public: + static GDBJITRegistrationListener &instance() { + static GDBJITRegistrationListener Instance; + return Instance; + } + /// Creates an entry in the JIT registry for the buffer @p Object, /// which must contain an object file in executable memory with any /// debug information for the debugger. @@ -121,10 +133,6 @@ private: void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I); }; -/// Lock used to serialize all jit registration events, since they -/// modify global variables. -ManagedStatic JITDebugLock; - /// Do the registration. void NotifyDebugger(jit_code_entry* JITCodeEntry) { __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; @@ -143,7 +151,7 @@ void NotifyDebugger(jit_code_entry* JITCodeEntry) { GDBJITRegistrationListener::~GDBJITRegistrationListener() { // Free all registered object files. - std::lock_guard locked(*JITDebugLock); + std::lock_guard locked(JITDebugLock); for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end(); I != E; ++I) { @@ -167,7 +175,7 @@ void GDBJITRegistrationListener::notifyObjectLoaded( const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart(); size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize(); - std::lock_guard locked(*JITDebugLock); + std::lock_guard locked(JITDebugLock); assert(ObjectBufferMap.find(K) == ObjectBufferMap.end() && "Second attempt to perform debug registration."); jit_code_entry* JITCodeEntry = new jit_code_entry(); @@ -186,7 +194,7 @@ void GDBJITRegistrationListener::notifyObjectLoaded( } void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) { - std::lock_guard locked(*JITDebugLock); + std::lock_guard locked(JITDebugLock); RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(K); if (I != ObjectBufferMap.end()) { @@ -228,14 +236,12 @@ void GDBJITRegistrationListener::deregisterObjectInternal( JITCodeEntry = nullptr; } -llvm::ManagedStatic GDBRegListener; - } // end namespace namespace llvm { JITEventListener* JITEventListener::createGDBRegistrationListener() { - return &*GDBRegListener; + return &GDBJITRegistrationListener::instance(); } } // namespace llvm -- 2.7.4