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

Nikos Mavrogiannopoulos nmav at gnutls.org
Thu Apr 6 13:17:17 CEST 2017

On Wed, Apr 5, 2017 at 5:52 PM, Lavrentiev, Anton (NIH/NLM/NCBI) [C]
<lavr at ncbi.nlm.nih.gov> wrote:
> Hello,
> 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.

That's quite interesting case. Is that particular issue happening
because of the way you are using gnutls, or would this happen to most
users in windows? Do you have a suggestion on what can be improved to
avoid these crashes? Skipping the deinitialization completely in
windows could be an option, but that would create leaks to
applications that use it via the equivalent of dlopen().

btw. you can disable the transparent initialization with an
environment variable:


More information about the Gnutls-help mailing list