From: Ivan Maidanski Date: Mon, 18 Sep 2017 07:54:37 +0000 (+0300) Subject: Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME X-Git-Tag: v8.0.0~586 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4d690e;p=gc Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME 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). --- diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index d4f1ed4c..45139dd4 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2666,7 +2666,6 @@ /* 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 @@ -3001,6 +3000,26 @@ # 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 607029c4..b79156d5 100644 --- 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. */