Eliminate TSan false positive for stop_info.stack_ptr
authorIvan Maidanski <ivmai@mail.ru>
Fri, 17 Nov 2017 16:41:30 +0000 (19:41 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 17 Nov 2017 16:41:30 +0000 (19:41 +0300)
Without this patch, Thread Sanitizer reports a data race between
GC_has_other_debug_info() and the code which sets stop_info.stack_ptr.

* include/private/pthread_support.h (GC_Thread_Rep.status): Move the
field to be before stop_info one (so, the latter now has the offset
of at least 3 in words, while oh.oh_sz has the offset of 2 in words
(when KEEP_BACK_PTRS, MAKE_BACK_GRAPH and NEED_CALLINFO are not
defined)).

include/private/pthread_support.h

index 4505453..20b08ea 100644 (file)
@@ -49,7 +49,19 @@ typedef struct GC_Thread_Rep {
 #   ifdef USE_TKILL_ON_ANDROID
       pid_t kernel_id;
 #   endif
-    /* Extra bookkeeping information the stopping code uses */
+
+    void * status;              /* The value returned from the thread.  */
+                                /* Used only to avoid premature         */
+                                /* reclamation of any data it might     */
+                                /* reference.                           */
+                                /* This is unfortunately also the       */
+                                /* reason we need to intercept join     */
+                                /* and detach.                          */
+
+    /* Extra bookkeeping information the stopping code uses.            */
+    /* Should have the offset of 3 (in words) at least, to avoid TSan   */
+    /* false positive about the race between GC_has_other_debug_info    */
+    /* and GC_suspend_handler_inner (which sets store_stop.stack_ptr).  */
     struct thread_stop_info stop_info;
 
     unsigned char flags;
@@ -105,14 +117,6 @@ typedef struct GC_Thread_Rep {
                         /* the innermost GC_call_with_gc_active() of    */
                         /* this thread.  May be NULL.                   */
 
-    void * status;              /* The value returned from the thread.  */
-                                /* Used only to avoid premature         */
-                                /* reclamation of any data it might     */
-                                /* reference.                           */
-                                /* This is unfortunately also the       */
-                                /* reason we need to intercept join     */
-                                /* and detach.                          */
-
 #   ifdef THREAD_LOCAL_ALLOC
         struct thread_local_freelists tlfs;
 #   endif