summaryrefslogtreecommitdiff
path: root/src/sysdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index a5b3117d262..2b735160763 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1876,6 +1876,11 @@ handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
too nested calls to mark_object. No way to survive. */
bool fatal = gc_in_progress;
+#if USE_INCREMENTAL_GC && WRITE_PROTECT_SIGNAL == SIGSEGV
+ if (alloc_fault (siginfo->si_addr))
+ return;
+#endif /* USE_INCREMENTAL_GC && WRITE_PROTECT_SIGNAL == SIGSEGV */
+
#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
if (!fatal && !pthread_equal (pthread_self (), main_thread_id))
fatal = true;
@@ -1963,11 +1968,28 @@ maybe_fatal_sig (int sig)
sigaction (sig, &process_fatal_action, 0);
}
+#ifdef USE_INCREMENTAL_GC
+
+static void
+write_protect_fault (int signal, siginfo_t *siginfo, void *arg)
+{
+ if (alloc_fault (siginfo->si_addr))
+ return;
+
+ /* Otherwise, this is another kind of fault. */
+ deliver_fatal_thread_signal (signal);
+}
+
+#endif /* USE_INCREMENTAL_GC */
+
void
init_signals (void)
{
struct sigaction thread_fatal_action;
struct sigaction action;
+#ifdef USE_INCREMENTAL_GC
+ bool was_sigsegv_init;
+#endif /* USE_INCREMENTAL_GC */
sigemptyset (&empty_mask);
@@ -2052,7 +2074,12 @@ init_signals (void)
sigaction (SIGBUS, &thread_fatal_action, 0);
#endif
if (!init_sigsegv ())
- sigaction (SIGSEGV, &thread_fatal_action, 0);
+ {
+#ifdef USE_INCREMENTAL_GC
+ was_sigsegv_init = true;
+#endif /* USE_INCREMENTAL_GC */
+ sigaction (SIGSEGV, &thread_fatal_action, 0);
+ }
#ifdef SIGSYS
sigaction (SIGSYS, &thread_fatal_action, 0);
#endif
@@ -2098,6 +2125,18 @@ init_signals (void)
#ifdef SIGTALRM
sigaction (SIGTALRM, &thread_fatal_action, 0);
#endif
+
+#ifdef USE_INCREMENTAL_GC
+#if WRITE_PROTECT_SIGNAL == SIGSEGV
+ if (!was_sigsegv_init)
+#endif /* WRITE_PROTECT_SIGNAL == SIGSEGV */
+ {
+ memset (&action, 0, sizeof action);
+ action.sa_flags = SA_SIGINFO;
+ action.sa_sigaction = write_protect_fault;
+ sigaction (WRITE_PROTECT_SIGNAL, &action, 0);
+ }
+#endif /* USE_INCREMENTAL_GC */
}
#ifndef HAVE_RANDOM