This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: dlclose blocked by static-initialized member of templated class


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-----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]