This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: dlclose blocked by static-initialized member of templated class
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: Jan Engelhardt <jengelh at inai dot de>
- Cc: libc-help at sourceware dot org
- Date: Mon, 27 Jul 2015 18:42:10 +0200
- Subject: Re: dlclose blocked by static-initialized member of templated class
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 20 dot 1507271807430 dot 15792 at nerf40 dot vanv dot qr>
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-----