]> granicus.if.org Git - gc/commitdiff
Eliminate TSan warning about data race when accessing GC_debugging_started
authorIvan Maidanski <ivmai@mail.ru>
Fri, 17 Nov 2017 08:07:03 +0000 (11:07 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 16 Apr 2018 08:25:05 +0000 (11:25 +0300)
Now GC_debugging_started variable is double-checked with the allocation
lock held before calling GC_start_debugging_inner.

* dbg_mlc.c (GC_start_debugging_inner): Define as GC_INNER (instead of
STATIC).
* dbg_mlc.c [THREADS] (GC_start_debugging): Define as STATIC; do not
call GC_start_debugging_inner() if GC_debugging_started.
* dbg_mlc.c [!THREADS] (GC_start_debugging): Define as macro (redirect
to GC_start_debugging_inner).
* gcj_mlc.c (GC_debug_gcj_malloc): Call GC_start_debugging_inner
(holding the lock) instead of GC_start_debugging.
* include/private/gc_priv.h (GC_start_debugging): Rename to
GC_start_debugging_inner; improve usage comment.

dbg_mlc.c
gcj_mlc.c
include/private/gc_priv.h

index 4701b0d0c395b711cc072f12b3ce91ad91e01e6a..ae3efa197997cd3f74bfaac1b2857d05f77ac0f0 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -465,7 +465,7 @@ STATIC void GC_debug_print_heap_obj_proc(ptr_t p)
   STATIC void GC_do_nothing(void) {}
 #endif
 
-STATIC void GC_start_debugging_inner(void)
+GC_INNER void GC_start_debugging_inner(void)
 {
   GC_ASSERT(I_HOLD_LOCK());
 # ifndef SHORT_DBG_HDRS
@@ -480,14 +480,19 @@ STATIC void GC_start_debugging_inner(void)
   GC_register_displacement_inner((word)sizeof(oh));
 }
 
-GC_INNER void GC_start_debugging(void)
-{
-  DCL_LOCK_STATE;
+#ifdef THREADS
+  STATIC void GC_start_debugging(void)
+  {
+    DCL_LOCK_STATE;
 
-  LOCK();
-  GC_start_debugging_inner();
-  UNLOCK();
-}
+    LOCK();
+    if (!GC_debugging_started)
+      GC_start_debugging_inner();
+    UNLOCK();
+  }
+#else
+# define GC_start_debugging GC_start_debugging_inner
+#endif /* !THREADS */
 
 size_t GC_debug_header_size = sizeof(oh);
 
index 7b4ea9daedafab999dd64e3dd306f4858b68dc62..bcd95b05d7a9f71fb20e2843d165c64ab5f787da 100644 (file)
--- a/gcj_mlc.c
+++ b/gcj_mlc.c
@@ -219,10 +219,10 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_gcj_malloc(size_t lb,
         return((*oom_fn)(lb));
     }
     *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
-    UNLOCK();
     if (!GC_debugging_started) {
-        GC_start_debugging();
+        GC_start_debugging_inner();
     }
+    UNLOCK();
     ADD_CALL_CHAIN(result, ra);
     return (GC_store_debug_info(result, (word)lb, s, i));
 }
index 8350b6505d9ad4adccab48fb9dc5a5869b93b6be..eddbe27b4e843a13f4fe71bd4b5281c71e29a122 100644 (file)
@@ -2324,7 +2324,8 @@ GC_INNER void GC_initialize_offsets(void);      /* defined in obj_map.c */
 GC_INNER void GC_bl_init(void);
 GC_INNER void GC_bl_init_no_interiors(void);    /* defined in blacklst.c */
 
-GC_INNER void GC_start_debugging(void); /* defined in dbg_mlc.c */
+GC_INNER void GC_start_debugging_inner(void);   /* defined in dbg_mlc.c. */
+                        /* Should not be called if GC_debugging_started. */
 
 /* Store debugging info into p.  Return displaced pointer.      */
 /* Assumes we don't hold allocation lock.                       */