From: Ivan Maidanski Date: Mon, 28 Aug 2017 08:26:51 +0000 (+0300) Subject: Fix assertion violation in return_single_freelist in child process X-Git-Tag: v7.6.2~83 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc6d375c12eb2287c71ee48674416c265706e95c;p=gc Fix assertion violation in return_single_freelist in child process Issue #171 (bdwgc). GC_destroy_thread_local cannot be called from a thread other than the current one. * pthread_support.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC] (GC_remove_all_threads_but_me): Do not call GC_destroy_thread_local; add comment. * win32_threads.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC] (GC_remove_all_threads_but_me): Likewise. * thread_local_alloc.c [THREAD_LOCAL_ALLOC] (GC_destroy_thread_local): Update comment. --- diff --git a/pthread_support.c b/pthread_support.c index a4143169..f3d7065a 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -773,7 +773,12 @@ STATIC void GC_remove_all_threads_but_me(void) } else { # ifdef THREAD_LOCAL_ALLOC if (!(p -> flags & FINISHED)) { - GC_destroy_thread_local(&(p->tlfs)); + /* Cannot call GC_destroy_thread_local here. The free */ + /* lists may be in an inconsistent state (as thread p may */ + /* be updating one of the lists by GC_generic_malloc_many */ + /* or GC_FAST_MALLOC_GRANS when fork is invoked). */ + /* This should not be a problem because the lost elements */ + /* of the free lists will be collected during GC. */ GC_remove_specific_after_fork(GC_thread_key, p -> id); } # endif diff --git a/thread_local_alloc.c b/thread_local_alloc.c index 3951fe71..25568b46 100644 --- a/thread_local_alloc.c +++ b/thread_local_alloc.c @@ -129,8 +129,7 @@ GC_INNER void GC_destroy_thread_local(GC_tlfs p) { int k; - /* We currently only do this from the thread itself or from */ - /* the fork handler for a child process. */ + /* We currently only do this from the thread itself. */ GC_STATIC_ASSERT(THREAD_FREELISTS_KINDS <= MAXOBJKINDS); for (k = 0; k < THREAD_FREELISTS_KINDS; ++k) { if (k == (int)GC_n_kinds) diff --git a/win32_threads.c b/win32_threads.c index 634ebf0a..97e8c6ea 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -1033,7 +1033,8 @@ GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn, } else { # ifdef THREAD_LOCAL_ALLOC if ((p -> flags & FINISHED) == 0) { - GC_destroy_thread_local(&p->tlfs); + /* Cannot call GC_destroy_thread_local here (see the */ + /* corresponding comment in pthread_support.c). */ GC_remove_specific_after_fork(GC_thread_key, p -> pthread_id); } # endif