Bug #18796 ยป 0001-Disable-Mach-exception-handlers-when-read-barriers-i.patch
| configure.ac | ||
|---|---|---|
|
AS_IF([test "x$ac_cv_header_execinfo_h" = xyes], [
|
||
|
AC_CHECK_LIB([execinfo], [backtrace])
|
||
|
AC_CHECK_HEADERS([libunwind.h])
|
||
|
AC_CHECK_HEADERS([mach/task.h mach/mach_init.h mach/mach_port.h])
|
||
|
AS_IF([ test \
|
||
|
"x${ac_cv_header_mach_task_h}" = xyes -a \
|
||
|
"x${ac_cv_header_mach_mach_init_h}" = xyes -a \
|
||
|
"x${ac_cv_header_mach_mach_port_h}" = xyes \
|
||
|
], [
|
||
|
AC_DEFINE([HAVE_MACH_TASK_EXCEPTION_PORTS], [1])
|
||
|
])
|
||
|
])],
|
||
|
[*-freebsd*|x86_64-netbsd*], [
|
||
|
AC_CHECK_HEADERS([execinfo.h])
|
||
| gc.c | ||
|---|---|---|
|
#include <emscripten.h>
|
||
|
#endif
|
||
|
#ifdef HAVE_MACH_TASK_EXCEPTION_PORTS
|
||
|
# include <mach/task.h>
|
||
|
# include <mach/mach_init.h>
|
||
|
# include <mach/mach_port.h>
|
||
|
#endif
|
||
|
#undef LIST_HEAD /* ccan/list conflicts with BSD-origin sys/queue.h. */
|
||
|
#include "constant.h"
|
||
| ... | ... | |
|
static struct sigaction old_sigbus_handler;
|
||
|
static struct sigaction old_sigsegv_handler;
|
||
|
#ifdef HAVE_MACH_TASK_EXCEPTION_PORTS
|
||
|
static exception_mask_t old_exception_masks[32];
|
||
|
static mach_port_t old_exception_ports[32];
|
||
|
static exception_behavior_t old_exception_behaviors[32];
|
||
|
static thread_state_flavor_t old_exception_flavors[32];
|
||
|
static mach_msg_type_number_t old_exception_count;
|
||
|
static void
|
||
|
disable_mach_bad_access_exc()
|
||
|
{
|
||
|
old_exception_count = sizeof(old_exception_masks) / sizeof(old_exception_masks[0]);
|
||
|
task_swap_exception_ports(
|
||
|
mach_task_self(), EXC_MASK_BAD_ACCESS,
|
||
|
MACH_PORT_NULL, EXCEPTION_DEFAULT, 0,
|
||
|
old_exception_masks, &old_exception_count,
|
||
|
old_exception_ports, old_exception_behaviors, old_exception_flavors
|
||
|
);
|
||
|
}
|
||
|
static void
|
||
|
restore_mach_bad_access_exc()
|
||
|
{
|
||
|
for (mach_msg_type_number_t i = 0; i < old_exception_count; i++) {
|
||
|
task_set_exception_ports(
|
||
|
mach_task_self(),
|
||
|
old_exception_masks[i], old_exception_ports[i],
|
||
|
old_exception_behaviors[i], old_exception_flavors[i]
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
static void
|
||
|
read_barrier_signal(int sig, siginfo_t * info, void * data)
|
||
|
{
|
||
| ... | ... | |
|
sigaddset(&set, SIGBUS);
|
||
|
sigaddset(&set, SIGSEGV);
|
||
|
sigprocmask(SIG_UNBLOCK, &set, &prev_set);
|
||
|
#ifdef HAVE_MACH_TASK_EXCEPTION_PORTS
|
||
|
disable_mach_bad_access_exc();
|
||
|
#endif
|
||
|
// run handler
|
||
|
read_barrier_handler((uintptr_t)info->si_addr);
|
||
|
// reset SEGV/BUS handlers
|
||
|
#ifdef HAVE_MACH_TASK_EXCEPTION_PORTS
|
||
|
restore_mach_bad_access_exc();
|
||
|
#endif
|
||
|
sigaction(SIGBUS, &prev_sigbus, NULL);
|
||
|
sigaction(SIGSEGV, &prev_sigsegv, NULL);
|
||
|
sigprocmask(SIG_SETMASK, &prev_set, NULL);
|
||
| ... | ... | |
|
static void
|
||
|
uninstall_handlers(void)
|
||
|
{
|
||
|
#ifdef HAVE_MACH_TASK_EXCEPTION_PORTS
|
||
|
restore_mach_bad_access_exc();
|
||
|
#endif
|
||
|
sigaction(SIGBUS, &old_sigbus_handler, NULL);
|
||
|
sigaction(SIGSEGV, &old_sigsegv_handler, NULL);
|
||
|
}
|
||
| ... | ... | |
|
sigaction(SIGBUS, &action, &old_sigbus_handler);
|
||
|
sigaction(SIGSEGV, &action, &old_sigsegv_handler);
|
||
|
#ifdef HAVE_MACH_TASK_EXCEPTION_PORTS
|
||
|
disable_mach_bad_access_exc();
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|
||