New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pthread_key_create() and unloading via dlclose() probably mutually incompatible #653
Comments
I'd be interested to see a patch to do this. |
I'll write one on Friday. |
Also, where there is no |
@nicowilliams great! I'm looking forward to seeing that. |
The thought occurs that valgrind ought to have an option to ignore leaks where |
I can't believe I forgot, but there's the link-editor What I don't quite know is how to hack on the OpenSSL build configuration system to use this, much less use it where it's actually supported by |
Is there a good resource for how to hack on the OpenSSL build configuration system? IIUC Richard Levitte is revamping it. |
There's at least a start in Otherwise, I think that @dot-asm had something along these lines started, but I haven't seen much news on that lately (and yeah, @dot-asm, this was a very purposeful nudge ;-)) |
If we go with |
Ping @nicowilliams. So what to do about this one? I did some testing and discovered/verified a couple of things:
Probably, where we can, we should build with |
Ping @nicowilliams ...any further thoughts on this? |
I am now thinking that, given my above results, perhaps a documentation fix is sufficient. Perhaps there are times where using |
I also tested this on Windows using LoadLibrary and FreeLibrary (instead of dlopen and dlclose). The behaviour is much the same on Windows as it is on Unix (except there is no RTLD_NODELETE AFAIK). |
If using threads and OpenSSL is loaded via dlopen(), and subsequently closed again via dlclose() *before* the threads are destroyed, then OpenSSL will not free up the per thread resources. We need to document this restriction, and provide some guidance on what to do about it. I did some testing and discovered/verified a few of things (at least this is the behaviour on Linux): - Using OpenSSL via dlopen in a mutli-threaded app does leak memory if threads are destroyed after dlcose() is called. - In a single threaded environment, or if threads are destroyed prior to dlclose() being called, then no memory is leaked - Using the RTLD_NODELETE flag to dlopen solves the above problem - Interestingly the OpenSSL atexit() handler gets called when dlclose() is called rather than at application exit (I was worred that it might crash if there was an atexit() handler for a function that has been unloaded) - RTLD_NODELETE is a non-standard flag - but it does seem to be fairly widely supported. As far as I could determine (via google), at least Linux, Solaris, OpenBSD, FreeBSD, HP-UX all seem to support it. I also tested on Windows (using LoadLibrary instead of dlopen and FreeLibrary instead of dlclose) and experienced similar behaviour, except that (AFAIK) there is no equivalent of RTLD_NODELETE on Windows. GitHub Issue #653 Reviewed-by: Richard Levitte <levitte@openssl.org>
Documentation updated in c796e02. Closing. |
Viktor prods me to comment on this in relation to rt 3824 https://rt.openssl.org/Ticket/Display.html?id=3824.
There's no guarantee that a thread-specific's value destructor will be called for all keys before a shared object providing that destructor gets unloaded via last
dlcose()
call. There seems to be no standard or otherwise portable, or even non-portable way to do this.One can imagine wrapping all thread-specific values with a wrapper that is put on a global list so that a
.fini
section can clean them up. But this doesn't work: the destructor function pointer will still be associated with the thread-specific key and as soon as a thread exits the process will blow up as the destructor pointer will be invalid (or worse: perhaps some other object got loaded, ormmap()
occurred, such that said pointer now lies in valid address space, but it will still be invalid).The thing to do in [self-]initialization is to call
dladdr()
-if available- thendlopen()
the resultingdli_fname
, then leak the resultingdl
handle, thereby making sure that the library is never unloaded.The text was updated successfully, but these errors were encountered: