From da6d0b21ea6f4723bc550a05a87067167df34d01 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Mon, 18 Sep 2017 10:54:37 +0300 Subject: [PATCH] Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME (Cherry-pick commit 18fcc40 from 'release-7_4' 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). --- include/private/gc_pmark.h | 2 +- include/private/gcconfig.h | 21 ++++++++++++++++++++- mark.c | 13 ------------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/private/gc_pmark.h b/include/private/gc_pmark.h index 7e302d20..9581214b 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 "private/config.h" #endif diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 655f1edd..c06aec46 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2353,7 +2353,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 @@ -2603,6 +2602,26 @@ # define 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(PLATFORM_ANDROID) && !defined(THREADS) \ && !defined(USE_GET_STACKBASE_FOR_MAIN) /* Always use pthread_attr_getstack on Android ("-lpthread" option is */ diff --git a/mark.c b/mark.c index a6213dc9..375201f4 100644 --- a/mark.c +++ b/mark.c @@ -279,19 +279,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) - /* 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. */ -- 2.40.0