From 3a524692806bde17a7b668f96c0a687f653f3a21 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 23 Nov 2017 01:58:40 +0300 Subject: [PATCH] Workaround TSan false positives for at-fork handlers accessing lock_holder * pthread_support.c (GC_wait_for_gc_completion): Skip I_HOLD_LOCK() assertion if THREAD_SANITIZER and CAN_HANDLE_FORK; add comment. * pthread_support.c [CAN_HANDLE_FORK && GC_ASSERTIONS] (fork_prepare_proc, fork_parent_proc, fork_child_proc): Add GC_ATTR_NO_SANITIZE_THREAD attribute. --- pthread_support.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pthread_support.c b/pthread_support.c index 90602de2..70b512af 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -1001,7 +1001,11 @@ STATIC void GC_remove_all_threads_but_me(void) STATIC void GC_wait_for_gc_completion(GC_bool wait_for_all) { DCL_LOCK_STATE; - GC_ASSERT(I_HOLD_LOCK()); +# if !defined(THREAD_SANITIZER) || !defined(CAN_HANDLE_FORK) + /* GC_lock_holder is accessed with the lock held, so there is no */ + /* data race actually (unlike what is reported by TSan). */ + GC_ASSERT(I_HOLD_LOCK()); +# endif ASSERT_CANCEL_DISABLED(); if (GC_incremental && GC_collection_in_progress()) { word old_gc_no = GC_gc_no; @@ -1035,6 +1039,10 @@ IF_CANCEL(static int fork_cancel_state;) /* protected by allocation lock. */ /* Called before a fork() */ +#ifdef GC_ASSERTIONS + /* GC_lock_holder is updated safely (no data race actually). */ + GC_ATTR_NO_SANITIZE_THREAD +#endif static void fork_prepare_proc(void) { /* Acquire all relevant locks, so that after releasing the locks */ @@ -1059,6 +1067,9 @@ static void fork_prepare_proc(void) } /* Called in parent after a fork() (even if the latter failed). */ +#ifdef GC_ASSERTIONS + GC_ATTR_NO_SANITIZE_THREAD +#endif static void fork_parent_proc(void) { # if defined(PARALLEL_MARK) @@ -1070,6 +1081,9 @@ static void fork_parent_proc(void) } /* Called in child after a fork() */ +#ifdef GC_ASSERTIONS + GC_ATTR_NO_SANITIZE_THREAD +#endif static void fork_child_proc(void) { /* Clean up the thread table, so that just our thread is left. */ -- 2.40.0