Index: lib/Support/DynamicLibrary.cpp =================================================================== --- lib/Support/DynamicLibrary.cpp +++ lib/Support/DynamicLibrary.cpp @@ -128,9 +128,14 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName, std::string *Err) { SmartScopedLock Lock(*SymbolsMutex); + + // Force OpenedHandles to be added into the ManagedStatic list before any + // ManagedStatic can be added from static constructors in HandleSet::DLOpen. + HandleSet& HS = *OpenedHandles; + void *Handle = HandleSet::DLOpen(FileName, Err); if (Handle != &Invalid) - OpenedHandles->AddLibrary(Handle, /*IsProcess*/ FileName == nullptr); + HS.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr); return DynamicLibrary(Handle); } Index: unittests/Support/DynamicLibrary/CMakeLists.txt =================================================================== --- unittests/Support/DynamicLibrary/CMakeLists.txt +++ unittests/Support/DynamicLibrary/CMakeLists.txt @@ -10,6 +10,8 @@ SHARED PipSqueak.cxx ) +target_link_libraries(PipSqueak LLVMSupport) + set_output_directory(PipSqueak BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} Index: unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp =================================================================== --- unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp +++ unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp @@ -32,7 +32,7 @@ #if defined(_WIN32) || (defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)) -typedef void (*SetStrings)(std::string &GStr, std::string &LStr); +typedef void (*SetStrings)(std::string &GStr, std::string &LStr, std::string &MStr); typedef const char *(*GetString)(); template static T FuncPtr(void *Ptr) { @@ -98,7 +98,7 @@ } TEST(DynamicLibrary, Shutdown) { - std::string A, B; + std::string A, B, C; { std::string Err; llvm_shutdown_obj Shutdown; @@ -111,11 +111,12 @@ DynamicLibrary::SearchForAddressOfSymbol("SetStrings")); EXPECT_TRUE(SS != nullptr); - SS(A, B); + SS(A, B, C); EXPECT_EQ(B, "Local::Local"); } EXPECT_EQ(A, "Global::~Global"); EXPECT_EQ(B, "Local::~Local"); + EXPECT_EQ(C, "MangedStaticObj::~MangedStaticObj"); EXPECT_TRUE(FuncPtr(DynamicLibrary::SearchForAddressOfSymbol( "SetStrings")) == nullptr); } Index: unittests/Support/DynamicLibrary/PipSqueak.cxx =================================================================== --- unittests/Support/DynamicLibrary/PipSqueak.cxx +++ unittests/Support/DynamicLibrary/PipSqueak.cxx @@ -8,11 +8,23 @@ //===----------------------------------------------------------------------===// #include "PipSqueak.h" +#include "llvm/Support/ManagedStatic.h" #include +// +struct MangedStaticObj { + std::string *Str; + MangedStaticObj() : Str(nullptr) {} + ~MangedStaticObj() { if (Str) *Str = "MangedStaticObj::~MangedStaticObj"; } +}; +llvm::ManagedStatic LocalMangedStatic; + struct Global { std::string *Str; - Global() : Str(nullptr) {} + Global() : Str(nullptr) { + // Force LocalMangedStatic construction durring DLOpen + *LocalMangedStatic; + } ~Global() { if (Str) *Str = "Global::~Global"; @@ -28,9 +40,11 @@ static Global Glb; extern "C" PIPSQUEAK_EXPORT void SetStrings(std::string &GStr, - std::string &LStr) { + std::string &LStr, + std::string &MStr) { static Local Lcl(LStr); Glb.Str = &GStr; + LocalMangedStatic->Str = &MStr; } extern "C" PIPSQUEAK_EXPORT const char *TestA() { return "LibCall"; }