Narase Narase - 4 months ago 23
C++ Question

How to handle a changed Library opened with dlopen()

I'm using a shared object in my program which is loaded via dlopen().
When I overwrite the library with

mv debug/ plugin/
my program crashes as soon as it tries to interact with the loaded library. I cant even use dlclose(), this gets me a SIGSEV.

What is the best way to handle with this situations?

OS is Linux

Edit: actual code

void DynamicallyLoadedLibrary::loadLibrary() {
// ModificationTime updaten
lastModificationTime = modificationTime();

// Library laden
libraryHandle = dlopen(path.c_str(), RTLD_NOW);

if (!libraryHandle) { // Library gefunden?
throw DynamicLibraryException("Dynamic Library not found: " + path + "\n" + dlerror());

// Funktion laden
externalFunction = (dll_function) dlsym(libraryHandle, "run");

char *error;
if ((error = dlerror()) != NULL) { // Funktion gefunden?
throw DynamicLibraryException("Dynamic Library not found: run()\n" + string(error));

void DynamicallyLoadedLibrary::close() {
if (libraryHandle != nullptr) {
cout << "DLL/close(): " << dlclose(libraryHandle) << endl; // DEBUG
libraryHandle = nullptr;
externalFunction = nullptr;

void DynamicallyLoadedLibrary::operator()(vector<shared_ptr<ServerData>> &data) {
// Wenn Datei sich geaendert hat, neu laden
if (fileChanged()) {


Edit 2: The Library (UA_String is from
Its simply build with eclipse and copied in [...]/plugins. Execution works fine until I overwrite it

extern "C" void run(vector<shared_ptr<ServerData>> &data) {
cout << "++++ OPC_WORKING_PACKAGE EXTERN ++++" << endl; // XXX
for (unsigned int i = 0; i < data.size(); i++){
UA_String *uaString = (UA_String*) data[i]->dataReference();
cout << string((char*) uaString->data, uaString->length) << endl;
cout << "---- OPC_WORKING_PACKAGE EXTERN ----" << endl; // XXX


Your question is unclear.

If you have some /tmp/ and you do

void* dl = dlopen("/tmp/", TRL_NOW);

and later (in the same process) some

rename("/tmp/", "/tmp/")

(or even unlink("/tmp/"); ...) you should be able to dlclose(dl);

However, if your build process is making a new one, e.g. you have some make /tmp/ target, then you really should do a

 mv /tmp/ /tmp/ 

or even

 rm /tmp/

before linking the shared library, e.g. before

gcc -shared -Wall -O /tmp/plugin*.pic.o -o /tmp/

In other words, be sure that your build procedure is not overwriting bytes in the same inode (of the original /tmp/

So if you overwrite your old /tmp/ with some mv /tmp/ /tmp/ command in your build process you'll better do a mv /tmp/ /tmp/ or a rm /tmp/ just before.

Notice that mmap(2) (internally invoked by dlopen(3)) is actually working on opened inodes. See path_resolution(7). So you could unlink(2) your shared library while still having it dlopen-ed.

So never overwrite bytes in an existing shared library inode; do whatever is necessary to be sure to create a fresh shared library inode in your plugin build procedure.

Read Advanced Linux Programming & Drepper's How to Write a Shared Library

BTW, the real issue is not related to dlopen but to the nature of file descriptors (that is, of opened inodes) on POSIX systems (on which several processes can read and write the same file).

Use also pmap(1) (as pmap 1234) and/or cat /proc/1234/maps to understand the memory mapping of process of pid 1234 (i.e. its virtual address space).

PS. Copying in a private copy the shared object before dlopen might improve the situation, but does not solve the issue (what if the shared object source gets updated during the copy?). The real bug is in the build process which overwrites a shared object instead of writing & creating a pristine new inode.