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: v7.6.2~71 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=317a07a0732120b7a24e107f334ef4fcaeee47b1;p=gc Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME (Cherry-pick commits f4d690e, b874d02 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). --- diff --git a/include/private/gc_pmark.h b/include/private/gc_pmark.h index 6c0aadc1..34057c03 100644 --- a/include/private/gc_pmark.h +++ b/include/private/gc_pmark.h @@ -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 diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index d19ffd72..b7a139f6 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2673,7 +2673,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 @@ -2998,6 +2997,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 da3a59bd..9cb6f2e4 100644 --- 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. */