From acb2ccc48dec32d5e900a1b211376a00de089198 Mon Sep 17 00:00:00 2001 From: Daniele Rapetti <5535617+Iximiel@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:15:42 +0100 Subject: [PATCH 1/4] adding EnsureGlobalDLOpen --- src/tools/DLLoader.cpp | 34 ++++++++++++++++++++++++++++++++++ src/tools/DLLoader.h | 10 ++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/tools/DLLoader.cpp b/src/tools/DLLoader.cpp index ec6527d825..b057173c64 100644 --- a/src/tools/DLLoader.cpp +++ b/src/tools/DLLoader.cpp @@ -20,6 +20,8 @@ along with plumed. If not, see . +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #include "DLLoader.h" +#include "Exception.h" + #include #ifdef __PLUMED_HAS_DLOPEN @@ -79,5 +81,37 @@ DLLoader::DLLoader() { // do nothing } +DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept { + + // dladddr might be not available + // this part should likely be protected in a __PLUMED_HAS_DLADDR ifdef +#ifdef __PLUMED_HAS_DLOPEN + Dl_info info; + int zeroIsError=dladdr(symbol, &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). + if(zeroIsError==0) { + plumed_merror() << "Failure in finding any object that contains the symbol "<< symbol; + } + // std::cerr << "Path: " << info.dli_fname << "\n"; + //This "promotes" to GLOBAL the object with the symbol pointed by ptr + handle_ = dlopen(info.dli_fname, RTLD_GLOBAL | RTLD_NOW); + // std::cerr << "Handle: " << handle << "\n"; +#else + //errormessage +#endif + +} + +DLLoader::EnsureGlobalDLOpen::~EnsureGlobalDLOpen() { +#ifdef __PLUMED_HAS_DLOPEN + if (handle_) { + dlclose(handle_); + } +#endif //__PLUMED_HAS_DLOPEN +} + } diff --git a/src/tools/DLLoader.h b/src/tools/DLLoader.h index 312f1f3178..b612dd7cad 100644 --- a/src/tools/DLLoader.h +++ b/src/tools/DLLoader.h @@ -55,6 +55,16 @@ class DLLoader { 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(); + }; }; } // namespace PLMD From 1c21651bce0c79f1701bc87ed85478129147b205 Mon Sep 17 00:00:00 2001 From: Daniele Rapetti <5535617+Iximiel@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:17:55 +0100 Subject: [PATCH 2/4] Reverted LOAD GLOBAL --- src/core/PlumedMain.cpp | 4 ++-- src/core/PlumedMain.h | 2 +- src/setup/Load.cpp | 5 +---- src/tools/DLLoader.cpp | 10 +++------- src/tools/DLLoader.h | 2 +- 5 files changed, 8 insertions(+), 15 deletions(-) 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 b057173c64..72d5f7fe82 100644 --- a/src/tools/DLLoader.cpp +++ b/src/tools/DLLoader.cpp @@ -39,13 +39,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 { @@ -93,7 +89,7 @@ DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept { // object, then these functions return 0. In this case, an error // message is not available via dlerror(3). if(zeroIsError==0) { - plumed_merror() << "Failure in finding any object that contains the symbol "<< symbol; + plumed_error() << "Failure in finding any object that contains the symbol "<< symbol; } // std::cerr << "Path: " << info.dli_fname << "\n"; //This "promotes" to GLOBAL the object with the symbol pointed by ptr diff --git a/src/tools/DLLoader.h b/src/tools/DLLoader.h index b612dd7cad..898895e09f 100644 --- a/src/tools/DLLoader.h +++ b/src/tools/DLLoader.h @@ -50,7 +50,7 @@ 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). From d4ed8477a2d2c5da6fd9390b851f9b82c2f42566 Mon Sep 17 00:00:00 2001 From: Daniele Rapetti <5535617+Iximiel@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:22:50 +0100 Subject: [PATCH 3/4] removed throws from EnsureGlobalDLOpen --- src/tools/DLLoader.cpp | 34 ++++++++++++++++++---------------- src/tools/DLLoader.h | 3 +++ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/tools/DLLoader.cpp b/src/tools/DLLoader.cpp index 72d5f7fe82..fad10b2580 100644 --- a/src/tools/DLLoader.cpp +++ b/src/tools/DLLoader.cpp @@ -20,7 +20,6 @@ along with plumed. If not, see . +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #include "DLLoader.h" -#include "Exception.h" #include @@ -78,27 +77,31 @@ DLLoader::DLLoader() { } DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept { - - // dladddr might be not available - // this part should likely be protected in a __PLUMED_HAS_DLADDR ifdef #ifdef __PLUMED_HAS_DLOPEN +#ifdef __PLUMED_HAS_DLADDR Dl_info info; - int zeroIsError=dladdr(symbol, &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). - if(zeroIsError==0) { - plumed_error() << "Failure in finding any object that contains the symbol "<< symbol; + if(dladdr(symbol, &info)!=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); + } - // std::cerr << "Path: " << info.dli_fname << "\n"; - //This "promotes" to GLOBAL the object with the symbol pointed by ptr - handle_ = dlopen(info.dli_fname, RTLD_GLOBAL | RTLD_NOW); - // std::cerr << "Handle: " << handle << "\n"; #else - //errormessage -#endif - + 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() { @@ -109,5 +112,4 @@ DLLoader::EnsureGlobalDLOpen::~EnsureGlobalDLOpen() { #endif //__PLUMED_HAS_DLOPEN } - -} +} // namespace PLMD diff --git a/src/tools/DLLoader.h b/src/tools/DLLoader.h index 898895e09f..e73d244ec0 100644 --- a/src/tools/DLLoader.h +++ b/src/tools/DLLoader.h @@ -64,6 +64,9 @@ class DLLoader { 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)) {} }; }; From 7d301b4b12fa530046d50833739ff81b7a35505a Mon Sep 17 00:00:00 2001 From: Daniele Rapetti <5535617+Iximiel@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:00:25 +0100 Subject: [PATCH 4/4] dladdr return now clearer --- src/tools/DLLoader.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/DLLoader.cpp b/src/tools/DLLoader.cpp index fad10b2580..e7139383fb 100644 --- a/src/tools/DLLoader.cpp +++ b/src/tools/DLLoader.cpp @@ -84,7 +84,8 @@ DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept { // 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). - if(dladdr(symbol, &info)!=0) { + 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 { @@ -92,7 +93,7 @@ DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept { "+++WARNING+++" "Failure in finding any object that contains the symbol %p.\n", symbol); - + } #else std::fprintf(stderr,