Skip to content

Commit

Permalink
Merge pull request #1000 from Iximiel/EnsureGlobalDLOpen
Browse files Browse the repository at this point in the history
Adding a RAII class to promote an object containt a symbol to be dlopened with RTLD_GLOBAL
  • Loading branch information
GiovanniBussi authored Dec 5, 2023
2 parents 91d56cb + 7d301b4 commit 5cbb885
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/core/PlumedMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(".");
Expand All @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/PlumedMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions src/setup/Load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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);
}

}
Expand Down
45 changes: 39 additions & 6 deletions src/tools/DLLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
along with plumed. If not, see <http://www.gnu.org/licenses/>.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#include "DLLoader.h"

#include <cstdlib>

#ifdef __PLUMED_HAS_DLOPEN
Expand All @@ -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 {
Expand Down Expand Up @@ -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
15 changes: 14 additions & 1 deletion src/tools/DLLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T> EnsureGlobalDLOpen(const T&p) noexcept
: EnsureGlobalDLOpen(reinterpret_cast<const void*>(p)) {}
};
};

} // namespace PLMD
Expand Down

2 comments on commit 5cbb885

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/a-masterclass-22-09.txt
Found broken examples in automatic/a-masterclass-22-11.txt
Found broken examples in automatic/a-masterclass-22-12.txt
Found broken examples in automatic/performance-optimization.txt
Found broken examples in automatic/a-trieste-6.txt
Found broken examples in automatic/munster.txt
Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/ENVIRONMENTSIMILARITY.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNCPATHGENERAL.tmp
Found broken examples in automatic/FUNCPATHMSD.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GHBFIX.tmp
Found broken examples in automatic/INCLUDE.tmp
Found broken examples in automatic/MAZE_MEMETIC_SAMPLING.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_RANDOM_WALK.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PLUMED.tmp
Found broken examples in MiscelaneousPP.md

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/a-masterclass-22-09.txt
Found broken examples in automatic/a-masterclass-22-11.txt
Found broken examples in automatic/a-masterclass-22-12.txt
Found broken examples in automatic/performance-optimization.txt
Found broken examples in automatic/a-trieste-6.txt
Found broken examples in automatic/munster.txt
Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/ENVIRONMENTSIMILARITY.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNCPATHGENERAL.tmp
Found broken examples in automatic/FUNCPATHMSD.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GHBFIX.tmp
Found broken examples in automatic/INCLUDE.tmp
Found broken examples in automatic/MAZE_MEMETIC_SAMPLING.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_RANDOM_WALK.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PLUMED.tmp
Found broken examples in MiscelaneousPP.md

Please sign in to comment.