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;
}