]> 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>
Mon, 18 Sep 2017 07:59:42 +0000 (10:59 +0300)
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).

* 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/gcconfig.h
mark.c

index d4f1ed4cf232cf6e1b7b2d18fe263c2b74fe0b4c..45139dd4d1c13438482a90684a09cb412173b119 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 607029c477883174ef3f6497a6291b2acb9e3861..b79156d5df06cc954591ad31fc7bdbf911935caa 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -298,20 +298,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.        */