diff --git a/src/core/PlumedMain.cpp b/src/core/PlumedMain.cpp index 1762a92e07..db604fdd3f 100644 --- a/src/core/PlumedMain.cpp +++ b/src/core/PlumedMain.cpp @@ -1091,7 +1091,7 @@ void PlumedMain::update() { } } -void PlumedMain::load(const std::string& fileName, const bool loadGlobal) { +void PlumedMain::load(const std::string& fileName) { if(DLLoader::installed()) { std::string libName=fileName; size_t n=libName.find_last_of("."); @@ -1118,7 +1118,7 @@ void PlumedMain::load(const std::string& fileName, const bool loadGlobal) { base="./"+base; } libName=base+"."+config::getSoExt(); - void *p=dlloader.load(libName,loadGlobal); + void *p=dlloader.load(libName); if(!p) { plumed_error()<<"I cannot load library " << fileName << " " << dlloader.error(); } diff --git a/src/core/PlumedMain.h b/src/core/PlumedMain.h index 73809aa243..635dc96379 100644 --- a/src/core/PlumedMain.h +++ b/src/core/PlumedMain.h @@ -368,7 +368,7 @@ class PlumedMain: /// Stop the run void exit(int c=0); /// Load a shared library - void load(const std::string&, bool=false); + void load(const std::string&); /// Get the suffix string const std::string & getSuffix()const; /// Set the suffix string diff --git a/src/setup/Load.cpp b/src/setup/Load.cpp index 36b10902ae..03283662e5 100644 --- a/src/setup/Load.cpp +++ b/src/setup/Load.cpp @@ -106,7 +106,6 @@ PLUMED_REGISTER_ACTION(Load,"LOAD") void Load::registerKeywords( Keywords& keys ) { ActionSetup::registerKeywords(keys); keys.add("compulsory","FILE","file to be loaded"); - keys.addFlag("GLOBAL",false,"when selected the shared object is LOADed with RTLD_GLOBAL instead of RTLD_LOCAL"); } Load::Load(const ActionOptions&ao): @@ -115,10 +114,8 @@ Load::Load(const ActionOptions&ao): { std::string f; parse("FILE",f); - bool loadWithGlobal=false; - parseFlag("GLOBAL",loadWithGlobal); checkRead(); - plumed.load(f,loadWithGlobal); + plumed.load(f); } } diff --git a/src/tools/DLLoader.cpp b/src/tools/DLLoader.cpp index ec6527d825..e7139383fb 100644 --- a/src/tools/DLLoader.cpp +++ b/src/tools/DLLoader.cpp @@ -20,6 +20,7 @@ along with plumed. If not, see . +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #include "DLLoader.h" + #include #ifdef __PLUMED_HAS_DLOPEN @@ -37,13 +38,9 @@ bool DLLoader::installed() { } -void* DLLoader::load(const std::string&s, const bool useGlobal) { +void* DLLoader::load(const std::string&s) { #ifdef __PLUMED_HAS_DLOPEN - void* p=nullptr; - if (useGlobal) - p=dlopen(s.c_str(),RTLD_NOW|RTLD_GLOBAL); - else - p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL); + void* p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL); if(!p) { lastError=dlerror(); } else { @@ -79,5 +76,41 @@ DLLoader::DLLoader() { // do nothing } +DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept { +#ifdef __PLUMED_HAS_DLOPEN +#ifdef __PLUMED_HAS_DLADDR + Dl_info info; + // from the manual: + // If the address specified in addr could not be matched to a shared + // object, then these functions return 0. In this case, an error + // message is not available via dlerror(3). + int zeroIsError=dladdr(symbol, &info); + if(zeroIsError!=0) { + //This "promotes" to GLOBAL the object with the symbol pointed by ptr + handle_ = dlopen(info.dli_fname, RTLD_GLOBAL | RTLD_NOW); + } else { + std::fprintf(stderr, + "+++WARNING+++" + "Failure in finding any object that contains the symbol %p.\n", + symbol); + + } +#else + std::fprintf(stderr, + "+++WARNING+++" + "I can't use dladdr for promoting the library containing the symbol %p.\n" + "This system seems not to support dladdr", + symbol); +#endif //__PLUMED_HAS_DLADDR +#endif //__PLUMED_HAS_DLOPEN +} +DLLoader::EnsureGlobalDLOpen::~EnsureGlobalDLOpen() { +#ifdef __PLUMED_HAS_DLOPEN + if (handle_) { + dlclose(handle_); + } +#endif //__PLUMED_HAS_DLOPEN } + +} // namespace PLMD diff --git a/src/tools/DLLoader.h b/src/tools/DLLoader.h index 312f1f3178..e73d244ec0 100644 --- a/src/tools/DLLoader.h +++ b/src/tools/DLLoader.h @@ -50,11 +50,24 @@ class DLLoader { /// Cleanup ~DLLoader(); /// Load a library, returning its handle - void* load(const std::string&, bool=false); + void* load(const std::string&); /// Returns the last error in dynamic loader const std::string & error(); /// Returns true if the dynamic loader is available (on some systems it may not). static bool installed(); + + /// RAII helper for promoting RTLD_LOCAL loaded objects to RTLD_GLOBAL + class EnsureGlobalDLOpen { + void* handle_=nullptr; + public: + /// makes sure that object defining ptr is globally available + explicit EnsureGlobalDLOpen(const void* symbol) noexcept; + /// dlclose the dlopened object + ~EnsureGlobalDLOpen(); + ///Confevert a const reference to a + template EnsureGlobalDLOpen(const T&p) noexcept + : EnsureGlobalDLOpen(reinterpret_cast(p)) {} + }; }; } // namespace PLMD