Only call thread-local destructors on DLL_THREAD_DETACH. In VS2015's debug runtime, the C runtime has been unloaded by the time DLL_PROCESS_DETACH is called and things crash. Instead, don't run destructors at that point. This means we do *not* free memory associated with any remaining thread-locals on application shutdown, only shutdown of individual threads. This is actually desirable since it's consistent with pthreads. If an individual thread calls pthread_exit, destructors are run. If the entire process exits, they are not. (It's also consistent with thread_none.c which never bothers to free anything.) BUG=chromium:595795 Change-Id: I3e64d46ea03158fefff583c1e3e12dfa0c0e172d Reviewed-on: https://boringssl-review.googlesource.com/7601 Reviewed-by: Steven Valdez <svaldez@google.com> Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/thread_win.c b/crypto/thread_win.c index e48ab5f..8e231eb 100644 --- a/crypto/thread_win.c +++ b/crypto/thread_win.c
@@ -150,9 +150,14 @@ g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES); } -static void NTAPI thread_local_destructor(PVOID module, - DWORD reason, PVOID reserved) { - if (DLL_THREAD_DETACH != reason && DLL_PROCESS_DETACH != reason) { +static void NTAPI thread_local_destructor(PVOID module, DWORD reason, + PVOID reserved) { + /* Only free memory on |DLL_THREAD_DETACH|, not |DLL_PROCESS_DETACH|. In + * VS2015's debug runtime, the C runtime has been unloaded by the time + * |DLL_PROCESS_DETACH| runs. See https://crbug.com/575795. This is consistent + * with |pthread_key_create| which does not call destructors on process exit, + * only thread exit. */ + if (reason != DLL_THREAD_DETACH) { return; }