[gnutls-help] DLL unload issues on Windows, MSVC2015 ReleaseDLL builds only

Lavrentiev, Anton (NIH/NLM/NCBI) [C] lavr at ncbi.nlm.nih.gov
Wed Apr 5 17:52:43 CEST 2017


We have recently had to work around a (very hard to get down to) issue of GNUTLS DLL's unloading bug that caused our (previously working) code start crashing way past the return from the main() function.

The crash happened when GNUTLS was attempting to deinit the mutexes that it created earlier (via the provided callbacks).  The reason was that since GNUTLS implicitly initializes itself (why, BTW?) in DllMain, any explicit global_init from our code just increased the init count, and global_deinit from our cleanup code, was called when the count was still 2, so no actual deinit occurred (and no mutexes have been freed).  Now, it looks like MVSC2015's RTL's ucrtbase.dll (that controls the app's heap) gets unloaded prior to GNUTLS DLL, zeroing up the heap base address, so any attempt to call free() lead to Access Violation (Exception 5) at address 0x74 (that's some offset that the heap manager uses to add to the base heap).  And that happened from GNUTLS's DLL fini (DESTRUCTOR) that followed ucrtbase.dll's fini sequence.

To work around, we have inserted a second global_deinit call to compensate for global_init (courtesy of DllMain), and so that it actually would do the cleanup.

We'd rather see a mutex leaking at the end of the process (we don't care, it's terminating, anyways) than to crash it altogether, because of the order that DLL's are unloading.  BTW, the run-time uses different version of free() in Debug mode, and so that does not crash at the end...


Anton Lavrentiev
Contractor NIH/NLM/NCBI

More information about the Gnutls-help mailing list