This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
dlclose blocked by static-initialized member of templated class
- From: Jan Engelhardt <jengelh at inai dot de>
- To: libc-help at sourceware dot org
- Date: Mon, 27 Jul 2015 18:18:12 +0200 (CEST)
- Subject: dlclose blocked by static-initialized member of templated class
- Authentication-results: sourceware.org; auth=none
Given the two snippets below, I observe that dlclose behaves like a no-op
under Linux x86_64 glibc-2.19.
1. Build module.cpp into module.so, build loader.c as a program.
2. Run the loader.
3. Observed behavior:
xxinit
#1 dlopen 0xwhatever
#2 dlopen 0xwhatever
Program done
xxexit
4. What was expected:
xxinit
#1 dlopen 0xwhatever
xxexit
xxinit
#2 dlopen 0xwhatever
xxexit
Program done
I can imagine that there is a justified reason related to libdl keeping
the reference count artificially higher, turning dlclose into a no-op,
though what exactly is going on?
-----8<-----(module.cpp)-----
#include <cstdio>
class nothing {};
template<typename _T> struct wrap {
static const int foo;
};
template<typename _T> const int wrap<_T>::foo(42);
static __attribute__((constructor)) void xxinit(void) { printf("xxinit\n"); }
static __attribute__((destructor)) void xxexit(void) { printf("xxexit\n"); }
void magic(wrap<nothing> p)
{
printf("%p\n", &p.foo); /* &p.foo causes the hold-up */
}
----->8------
-----8<------(loader.c)-----
#include <dlfcn.h>
#include <stdio.h>
int main(int argc, const char **argv)
{
void *h;
h = dlopen("./module.so", RTLD_NOW);
printf("#1 dlopen %p\n", h);
if (h != NULL)
dlclose(h);
h = dlopen("./module.so", RTLD_NOW);
printf("#2 dlopen %p\n", h);
if (h != NULL)
dlclose(h);
printf("Program done\n");
return 0;
}
----->8-----