From adf3ebe89196637592337108f4e8b33dfa10f3ef Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 14 Nov 2023 20:08:29 +0300 Subject: [PATCH] Fix lock assertion violation in GC_try_to_collect_inner on OS X (fix of commit b7b1004a2) Issue #583 (bdwgc). This happens only in the multi-threaded collector with assertions on and malloc redirection if GC_enable_incremental() is called. * include/private/gc_priv.h [MPROTECT_VDB && DARWIN]: Include pthread.h (wrapped into EXTERN_C_END/BEGIN). * include/private/gc_priv.h [MPROTECT_VDB && DARWIN && THREADS] (GC_inner_pthread_create): Declare (as GC_INNER function). * include/private/gc_priv.h [MPROTECT_VDB && DARWIN && !THREADS] (GC_inner_pthread_create): Define as macro (redirecting to pthread_create). * os_dep.c [MPROTECT_VDB && DARWIN]: Do not include pthread.h. * os_dep.c [MPROTECT_VDB && DARWIN] (pthread_create): Do not undefine. * os_dep.c [MPROTECT_VDB && DARWIN] (GC_dirty_init): Call GC_inner_pthread_create() instead of pthread_create(). * pthread_support.c [MPROTECT_VDB && DARWIN] (GC_inner_pthread_create): Define function (call INIT_REAL_SYMS() and REAL_FUNC(pthread_create)). --- include/private/gc_priv.h | 13 +++++++++++++ os_dep.c | 6 ++---- pthread_support.c | 10 ++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index de25d492e..5c39446d7 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -2588,6 +2588,19 @@ GC_EXTERN GC_bool GC_print_back_height; # endif # endif /* CAN_HANDLE_FORK */ +# if defined(MPROTECT_VDB) && defined(DARWIN) + EXTERN_C_END +# include + EXTERN_C_BEGIN +# ifdef THREADS + GC_INNER int GC_inner_pthread_create(pthread_t *t, + GC_PTHREAD_CREATE_CONST pthread_attr_t *a, + void *(*fn)(void *), void *arg); +# else +# define GC_inner_pthread_create pthread_create +# endif +# endif /* MPROTECT_VDB && DARWIN */ + GC_INNER GC_bool GC_dirty_init(void); /* Returns true if dirty bits are maintained (otherwise */ /* it is OK to be called again if the client invokes */ diff --git a/os_dep.c b/os_dep.c index 5a4a652e3..a2002831e 100644 --- a/os_dep.c +++ b/os_dep.c @@ -4393,7 +4393,6 @@ GC_INNER GC_bool GC_dirty_init(void) #include #include #include -#include EXTERN_C_BEGIN @@ -4767,9 +4766,8 @@ GC_INNER GC_bool GC_dirty_init(void) if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) ABORT("pthread_attr_setdetachedstate failed"); -# undef pthread_create - /* This will call the real pthread function, not our wrapper */ - if (pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0) + /* This will call the real pthread function, not our wrapper. */ + if (GC_inner_pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0) ABORT("pthread_create failed"); (void)pthread_attr_destroy(&attr); diff --git a/pthread_support.c b/pthread_support.c index 4421fedcd..cd2ba2dbc 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -260,6 +260,16 @@ static GC_bool parallel_initialized = FALSE; +#if defined(MPROTECT_VDB) && defined(DARWIN) + GC_INNER int GC_inner_pthread_create(pthread_t *t, + GC_PTHREAD_CREATE_CONST pthread_attr_t *a, + void *(*fn)(void *), void *arg) + { + INIT_REAL_SYMS(); + return REAL_FUNC(pthread_create)(t, a, fn, arg); + } +#endif + #ifndef GC_ALWAYS_MULTITHREADED GC_INNER GC_bool GC_need_to_lock = FALSE; #endif