Reputation: 1978
The question is as in the title and the following is the background:
On Linux, I'm trying to use dlopen() etc to build a C++ .so plugin framework that has a minimal and clean interface. That means:
makePluginObject()
with a path to the .so file being loaded and getting back a pointer to the object. Under the hood, this function calls dlopen() followed by the actual object allocation & construction. The object is of a C++ class whose implementation is in the .so.makePluginObject()
.) Crucially, there is no additional shutdown/teardown function for the user to explicitly call.The above design probably means that the code calling dlclose() is in the .so being dlopen'ed. The key question is this: Is it OK for code to call dlclose() on itself? I wonder because a naive implementation of dlclose() would unmap from memory the code that is still being run during object destruction.
It's important that the user interface remains this simple. The user just needs to call makePluginObject()
and delete the resulting pointer when he is done. If a teardown function is introduced that the user has to explicitly call after deleting the object, then the interface is much heavier and the burden on the user is much more. I know how to do things if an explicit teardown function is allowed and this question is not about that use case.
In my experiments, there were no crashes, but it seemed that dlclose() didn't really do anything because valgrind reported a lot of reachable memory associated with my call to dlopen().
Upvotes: 2
Views: 814
Reputation: 21955
Yes, calling dlclose
from library function will case a segfault, for the reasons you specified:
$ cat main.c
#include <dlfcn.h>
int main() {
void *h = dlopen("./liblib.so", RTLD_LAZY | RTLD_GLOBAL);
int (*foo)(void *) = dlsym(h, "foo");
foo(h);
return 0;
}
[y.gribov@link ~]$ cat lib.c
#include <dlfcn.h>
#include <stdio.h>
int foo(void *h) {
printf("Before dlclose\n");
dlclose(h);
printf("After dlclose\n");
return 10;
}
$ gcc main.c -ldl
$ gcc -o liblib.so lib.c -shared -fPIC -ldl
$ ./a.out
Before dlcose
Segmentation fault
It's unclear why it works in your particular case (your library may export GNU_UNIQUE
symbol, library may be dlopen
ed twice, etc.).
Upvotes: 2