From cad193e2a93ea1ce962936c179d61b84c28dab75 Mon Sep 17 00:00:00 2001 From: Frederich Munch <marsupial@users.noreply.github.com> Date: Fri, 30 Sep 2016 23:21:40 -0400 Subject: [PATCH] Implement atexit override. Windows uses atexit is to drive invoke static destructors, and using atexit on other platforms will cause cling to crash. --- .../include/cling/Interpreter/Interpreter.h | 4 ++++ .../cling/lib/Interpreter/Interpreter.cpp | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/interpreter/cling/include/cling/Interpreter/Interpreter.h b/interpreter/cling/include/cling/Interpreter/Interpreter.h index 8a74faabfea..fb1f76a53ce 100644 --- a/interpreter/cling/include/cling/Interpreter/Interpreter.h +++ b/interpreter/cling/include/cling/Interpreter/Interpreter.h @@ -282,6 +282,10 @@ namespace cling { /// void IncludeCRuntime(); + ///\brief Init atexit runtime delegation. + /// + void InitAExit(); + ///\brief The target constructor to be called from both the delegating /// constructors. parentInterp might be nullptr. /// diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp index e333ceec8a5..d57e467037d 100644 --- a/interpreter/cling/lib/Interpreter/Interpreter.cpp +++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp @@ -216,6 +216,8 @@ namespace cling { // Prevents stripping the symbol due to dead-code optimization. internal::symbol_requester(); } + + InitAExit(); } ///\brief Constructor for the child Interpreter. @@ -276,6 +278,25 @@ namespace cling { } } + void Interpreter::InitAExit() { + if (isInSyntaxOnlyMode()) + return; + + const char* Linkage = getCI()->getLangOpts().CPlusPlus ? "extern \"C\"" : ""; + llvm::SmallString<512> Buf; + llvm::raw_svector_ostream Strm(Buf); + Strm << Linkage << " int __cxa_atexit(void (*f) (void*), void*, void*);\n" + << Linkage << " int atexit(void(*f)()) {" + "return __cxa_atexit((void(*)(void*))f, nullptr, (void*)" + << m_Executor.get() << "); }\n"; + Transaction *T = nullptr; + declare(Strm.str(), &T); + if (llvm::Module* M = T ? T->getModule() : nullptr) { + if (const llvm::GlobalValue* GV = M->getNamedValue("atexit")) + m_Executor->getPointerToGlobalFromJIT(*GV); + } + } + void Interpreter::IncludeCXXRuntime() { // Set up common declarations which are going to be available // only at runtime -- GitLab