0

globals are bad I know, but even statics local to a function appear to be bad.

I noticed that on linux, globals and statics inside a shared object (dynamic library) are initialised the first time you use dlopen. But when you dlclose, and then dlopen again, it doesn't initialise globals or statics the second time.

I used RTLD_NOLOAD with dlopen to test if dlclose actually removed the libary, and it said it has, so this isn't a reference count issue.

This isn't the same as windows: http://msdn.microsoft.com/en-us/library/988ye33t.aspx Which I've tested and does appear to re-initialise statics.

Is this true, or am I just messing something else up?

If this is true, wouldn't this make any kind of static variable dangerous/useless?

3
  • 1
    From man 3 dlopen : flag RTLD_NODELETE : [...] the library's static variables are not reinitialized if the library is reloaded with dlopen() at a later time. [...]. Since this flag is not mandatory as contrary to RTLD_LAZY or RTLD_NOW flags, doesn't this imply that by default static variables should be reinitialized ? Commented Apr 4, 2014 at 22:21
  • Sweet, I had no idea there was a man page for nix/C++ functions like that. I'll take a look and see if there's a way to make it behave like the windows DLLs and reinitialise everything. But does this still mean that assuming anything about static initialisation is bad practice? Commented Apr 4, 2014 at 22:28
  • I downloaded the eglibc source and stepped into the dlopen function, and it's certainly doing something different the second time around. But where the choice is made is difficult to spot. The library is unloaded successfully it seems, so it shouldn't be hanging onto it. Sadly _fini() doesn't appear to work to catch when the library is closed. I'll come back tomorrow and try again. Commented Apr 5, 2014 at 0:00

1 Answer 1

2

But when you dlclose, and then dlopen again, it doesn't initialise globals or statics the second time.

This is most likely happening because the library was in fact not unloaded on dlclose.

From man dlclose

The function dlclose() decrements the reference count on the dynamic library handle handle. If the reference count drops to zero and no other loaded libraries use symbols in it, then the dynamic library is unloaded. 

It is most likely that you didn't satisfy "no other loaded libraries use symbols in it" part.

You can run the binary with LD_DEBUG=symbols,bindings and watch for messages like this:

 binding file XXX to libYYY.so: normal symbol `ZZZ' 

If you bind any symbols in libYYY.so to a file that is not unloaded, then libYYY.so can't be unloaded on dlclose.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, it appears as though there's a shared symbol keeping it open. Which means really, I need to change my approach and not assume dlclose actually calls destructors. Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.