Eliminate TSan warning about data race in default_on_abort
authorIvan Maidanski <ivmai@mail.ru>
Tue, 21 Nov 2017 19:10:22 +0000 (22:10 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 21 Nov 2017 19:10:22 +0000 (22:10 +0300)
The warning is about a potential race between GC_default_on_abort
(which updates GC_find_leak) and GC_finish_collection (which reads the
variable).

* misc.c [DONT_USE_ATEXIT && !PCR && !SMALL_CONFIG] (skip_gc_atexit):
New static variable; add comment.
* misc.c [DONT_USE_ATEXIT && (PCR || SMALL_CONFIG)] (skip_gc_atexit):
Define as macro (to FALSE).
* misc.c [DONT_USE_ATEXIT] (GC_exit_check): Do not call GC_gcollect
if skip_gc_atexit.
* misc.c [!PCR && !SMALL_CONFIG] (GC_default_on_abort): Do not modify
GC_find_leak.
* misc.c [DONT_USE_ATEXIT && !PCR && !SMALL_CONFIG]
(GC_default_on_abort): Set skip_gc_atexit to true.

misc.c

diff --git a/misc.c b/misc.c
index a94ecd3..231d7d1 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -716,9 +716,19 @@ GC_API int GC_CALL GC_is_init_called(void)
 #endif
 
 #ifndef DONT_USE_ATEXIT
+# if !defined(PCR) && !defined(SMALL_CONFIG)
+    /* A dedicated variable to avoid a garbage collection on abort.     */
+    /* GC_find_leak cannot be used for this purpose as otherwise        */
+    /* TSan finds a data race (between GC_default_on_abort and, e.g.,   */
+    /* GC_finish_collection).                                           */
+    static GC_bool skip_gc_atexit = FALSE;
+# else
+#   define skip_gc_atexit FALSE
+# endif
+
   STATIC void GC_exit_check(void)
   {
-    if (GC_find_leak) {
+    if (GC_find_leak && !skip_gc_atexit) {
       GC_gcollect();
     }
   }
@@ -1720,7 +1730,9 @@ GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void)
   /* and from EXIT() macro (msg is NULL in that case).                  */
   STATIC void GC_CALLBACK GC_default_on_abort(const char *msg)
   {
-    GC_find_leak = FALSE; /* disable at-exit GC_gcollect()  */
+#   ifndef DONT_USE_ATEXIT
+      skip_gc_atexit = TRUE; /* disable at-exit GC_gcollect() */
+#   endif
 
     if (msg != NULL) {
 #     if defined(MSWIN32)