From a6f2255dc7a02e8a1ae6eabe806694d6d1c2597b Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Tue, 27 Aug 2024 10:28:38 +0200 Subject: [PATCH] Fix lifetime of ClingMMapper The ClingMMapper must remain available until all ClingMemoryManagers are destructed, which is typically during shutdown of IncrementalJIT. This was not the case for the global object MMapperInstance that was introduced during the upgrade to LLVM 13 because libCling variables are destructed before running TROOT atexit handlers that shut down the JIT. In practice, it happened to work but this will change with the upgrade to LLVM 18 where we see crashes in some tests, potentially because of upstream commit https://github.com/llvm/llvm-project/commit/47f5c54f997a59bb2c65abe6b8b811f6e7553456 See also commits e0f6c04660 ("Prevent static destruction from ending DefaultMMapper too early") and 80c14bb948 ("Extend lifetime of SectionMemoryManager::DefaultMMapper, again") for the same problem that we previously patched in our copy of LLVM. --- lib/Interpreter/IncrementalJIT.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/Interpreter/IncrementalJIT.cpp b/lib/Interpreter/IncrementalJIT.cpp index 10ce77baba..7aa7696391 100644 --- a/lib/Interpreter/IncrementalJIT.cpp +++ b/lib/Interpreter/IncrementalJIT.cpp @@ -70,8 +70,6 @@ namespace { } }; - ClingMMapper MMapperInstance; - // A memory manager for Cling that reserves memory for code and data sections // to keep them contiguous for the emission of one module. This is required // for working exception handling support since one .eh_frame section will @@ -133,7 +131,7 @@ namespace { AllocInfo m_RWData; public: - ClingMemoryManager() : Super(&MMapperInstance) {} + ClingMemoryManager(ClingMMapper& MMapper) : Super(&MMapper) {} uint8_t* allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, @@ -474,7 +472,10 @@ IncrementalJIT::IncrementalJIT( return ObjLinkingLayer; } - auto GetMemMgr = []() { return std::make_unique(); }; + auto MMapper = std::make_unique(); + auto GetMemMgr = [MMapper = std::move(MMapper)]() { + return std::make_unique(*MMapper); + }; auto Layer = std::make_unique(ES, std::move(GetMemMgr));