dlclose blocked by static-initialized member of templated class
Ondřej Bílka
neleai@seznam.cz
Mon Jul 27 16:42:00 GMT 2015
On Mon, Jul 27, 2015 at 06:18:12PM +0200, Jan Engelhardt wrote:
>
> Given the two snippets below, I observe that dlclose behaves like a no-op
> under Linux x86_64 glibc-2.19.
>
Looks like STB_GNU_UNIQUE symbol, run following to see if there is entry
or not. Its that c++ guys decided that foo should be persistent versus
dlclose calls. See following:
http://stackoverflow.com/questions/11050693/dlclose-doesnt-work-with-factory-function-complex-static-in-function
> 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-----
More information about the Libc-help
mailing list