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