]> granicus.if.org Git - gc/commitdiff
Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME
authorIvan Maidanski <ivmai@mail.ru>
Mon, 18 Sep 2017 07:54:37 +0000 (10:54 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 28 Sep 2017 21:34:56 +0000 (00:34 +0300)
(Cherry-pick commits f4d690eb874d02 from 'master' branch.)

Issue #179 (bdwgc).

Parallel marker is disabled (for now) if there is a chance of
scanning unmapped data roots (because GC_do_local_mark is not
prepared to deal with memory protection faults gracefully).

* include/private/gc_pmark.h [HAVE_CONFIG_H]: Do not include config.h
if already included from gc_priv.h (to avoid PARALLEL_MARK macro
redefinition in config.h after it was undefined in gcconfig.h).
* mark.c [MSWIN32 || USE_PROC_FOR_LIBRARIES] (WRAP_MARK_SOME): Move
definition to gcconfig.h.
* include/private/gcconfig.h [WRAP_MARK_SOME && PARALLEL_MARK]
(PARALLEL_MARK): Undefine (as not implemented yet).

include/private/gc_pmark.h
include/private/gcconfig.h
mark.c

index 6c0aadc165b7c88f1ea2a0704682204d335e3c85..34057c0320e654690b20705d9f1ff3c3920c6691 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef GC_PMARK_H
 #define GC_PMARK_H
 
-#ifdef HAVE_CONFIG_H
+#if defined(HAVE_CONFIG_H) && !defined(GC_PRIVATE_H)
 # include "config.h"
 #endif
 
index d19ffd72c8fde0751f02ec4e9941c860d4c692aa..b7a139f6d6e0b1a90eabf31d2bfee50da7a21640 100644 (file)
     /* even with USE_PROC_FOR_LIBRARIES, we don't scan parts of stack   */
     /* segments that appear to be out of bounds.  Thus we actually      */
     /* do both, which seems to yield the best results.                  */
-
 #   define USE_PROC_FOR_LIBRARIES
 #endif
 
 # error "invalid config - PARALLEL_MARK requires GC_THREADS"
 #endif
 
+#if (((defined(MSWIN32) || defined(MSWINCE)) && !defined(__GNUC__)) \
+        || (defined(MSWIN32) && defined(I386)) /* for Win98 */ \
+        || (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))) \
+     && !defined(NO_WRAP_MARK_SOME)
+  /* Under rare conditions, we may end up marking from nonexistent      */
+  /* memory.  Hence we need to be prepared to recover by running        */
+  /* GC_mark_some with a suitable handler in place.                     */
+  /* TODO: Probably replace __GNUC__ above with ndef GC_PTHREADS.       */
+  /* FIXME: Should we really need it for WinCE?  If yes then            */
+  /* WRAP_MARK_SOME should be also defined for CeGCC which requires     */
+  /* CPU/OS-specific code in mark_ex_handler and GC_mark_some (for      */
+  /* manual stack unwinding and exception handler installation).        */
+# define WRAP_MARK_SOME
+#endif
+
+#if defined(WRAP_MARK_SOME) && defined(PARALLEL_MARK)
+  /* TODO: GC_mark_local does not handle memory protection faults yet.  */
+# undef PARALLEL_MARK
+#endif
+
 #if defined(PARALLEL_MARK) && !defined(DEFAULT_STACK_MAYBE_SMALL) \
     && (defined(HPUX) || defined(GC_DGUX386_THREADS) \
         || defined(NO_GETCONTEXT) /* e.g. musl */)
diff --git a/mark.c b/mark.c
index da3a59bdc0bc7c9b4e79ab6d9cc07ac6e9299f43..9cb6f2e4a81a24ae78c4e0ec01b88262bb37e4bd 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -289,20 +289,6 @@ STATIC struct hblk * GC_push_next_marked_uncollectable(struct hblk *h);
 
 static void alloc_mark_stack(size_t);
 
-# if (((defined(MSWIN32) || defined(MSWINCE)) && !defined(__GNUC__)) \
-        || (defined(MSWIN32) && defined(I386)) /* for Win98 */ \
-        || (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))) \
-     && !defined(NO_WRAP_MARK_SOME)
-    /* Under rare conditions, we may end up marking from nonexistent memory. */
-    /* Hence we need to be prepared to recover by running GC_mark_some       */
-    /* with a suitable handler in place.                                     */
-    /* FIXME: Should we really need it for WinCE?  If yes then          */
-    /* WRAP_MARK_SOME should be also defined for CeGCC which requires   */
-    /* CPU/OS-specific code in mark_ex_handler() and GC_mark_some()     */
-    /* (for manual stack unwinding and exception handler installation). */
-#   define WRAP_MARK_SOME
-# endif
-
 /* Perform a small amount of marking.                   */
 /* We try to touch roughly a page of memory.            */
 /* Return TRUE if we just finished a mark phase.        */