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
|
||