fault.
* bug fix: finalizers, gc hooks never run in a WITHOUT-INTERRUPTS
* bug fix: fix random memory faults related to interrupts on alpha
+ * bug fix: fix random memory faults related to interrupts on sparc
* bug fix: fix deadlocks related to starting threads
* bug fix: fix deadlines on locks on futex platforms
* bug fix: restore errno in signal handlers
*/
void
-memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context
+memory_fault_handler(int signal, siginfo_t *siginfo, os_context_t *context
#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
/* FreeBSD/amd64 stores fault address only in undocumented 4th arg. */
,void *fault_addr
#endif
)
{
- os_context_t *context = arch_os_get_context(&void_context);
#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
/* KLUDGE: Store fault address into si_addr for compatibilities. */
siginfo->si_addr = fault_addr;
#if defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
void
-mach_error_memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context) {
+mach_error_memory_fault_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context) {
lose("Unhandled memory fault. Exiting.");
}
#endif
#else /* Currently PPC/Darwin/Cheney only */
static void
-sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
#if 0
unsigned int pc = (unsigned int *)(*os_context_pc_addr(context));
#endif
}
static void
-sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context)
+sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int bad_inst;
bad_inst = *(unsigned int *)(*os_context_pc_addr(context) & ~3);
}
static void
-sigill_handler(int signal, siginfo_t *siginfo, void *void_context)
+sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int bad_inst;
bad_inst = *(unsigned int *)(*os_context_pc_addr(context) & ~3);
}
}
-static void sigfpe_handler(int signal, siginfo_t *siginfo, void *void_context)
+static void sigfpe_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int badinst;
int opcode, r1, r2, t;
long op1, op2, res;
the light of day. Since the instructions that we need to fix up
tend not to be doing unaligned memory access, this should be a safe
workaround. -- CSR, 2002-08-17 */
-static void sigbus_handler(int signal, siginfo_t *siginfo, void *void_context)
+static void sigbus_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int badinst;
int opcode, r1, r2, t;
long op1, op2, res;
}
static void
-ignore_handler(int signal, siginfo_t *siginfo, void *void_context)
+ignore_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
}
undoably_install_low_level_interrupt_handler(SIGXFSZ,ignore_handler);
#endif
}
-
*/
static void
-sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
os_vm_address_t addr = arch_get_bad_addr(signal, info, context);
if (!cheneygc_handle_wp_violation(context, addr))
* low_level_handle_now_handler
* low_level_maybe_now_maybe_later
* low_level_unblock_me_trampoline
+ *
+ * This gives us a single point of control (or six) over errno, fp
+ * control word, and fixing up signal context on sparc.
+ *
+ * The SPARC/Linux platform doesn't quite do signals the way we want
+ * them done. The third argument in the handler isn't filled in by the
+ * kernel properly, so we fix it up ourselves in the
+ * arch_os_get_context(..) function. -- CSR, 2002-07-23
*/
#define SAVE_ERRNO(context,void_context) \
{ \
errno = _saved_errno; \
}
-static void run_deferred_handler(struct interrupt_data *data, void *v_context);
+static void run_deferred_handler(struct interrupt_data *data,
+ os_context_t *context);
#ifndef LISP_FEATURE_WIN32
static void store_signal_data_for_later (struct interrupt_data *data,
void *handler, int signal,
boolean internal_errors_enabled = 0;
#ifndef LISP_FEATURE_WIN32
-static void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, void*);
+static
+void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, os_context_t*);
#endif
union interrupt_handler interrupt_handlers[NSIG];
arch_clear_pseudo_atomic_interrupted(context);
/* Restore the sigmask in the context. */
sigcopyset(os_context_sigmask_addr(context), &data->pending_mask);
- /* This will break on sparc linux: the deferred handler really
- * wants to be called with a void_context */
- run_deferred_handler(data,(void *)context);
+ run_deferred_handler(data, context);
}
/* It is possible that the end of this function was reached
* without never actually doing anything, the tests in Lisp for
#endif
}
\f
-/*
- * the two main signal handlers:
- * interrupt_handle_now(..)
- * maybe_now_maybe_later(..)
- *
- * to which we have added interrupt_handle_now_handler(..). Why?
- * Well, mostly because the SPARC/Linux platform doesn't quite do
- * signals the way we want them done. The third argument in the
- * handler isn't filled in by the kernel properly, so we fix it up
- * ourselves in the arch_os_get_context(..) function; however, we only
- * want to do this when we first hit the handler, and not when
- * interrupt_handle_now(..) is being called from some other handler
- * (when the fixup will already have been done). -- CSR, 2002-07-23
- */
void
interrupt_handle_now(int signal, siginfo_t *info, os_context_t *context)
* already; we're just doing the Lisp-level processing now that we
* put off then */
static void
-run_deferred_handler(struct interrupt_data *data, void *v_context)
+run_deferred_handler(struct interrupt_data *data, os_context_t *context)
{
/* The pending_handler may enable interrupts and then another
* interrupt may hit, overwrite interrupt_data, so reset the
* pending handler before calling it. Trust the handler to finish
* with the siginfo before enabling interrupts. */
- void (*pending_handler) (int, siginfo_t*, void*)=data->pending_handler;
+ void (*pending_handler) (int, siginfo_t*, os_context_t*) =
+ data->pending_handler;
data->pending_handler=0;
FSHOW_SIGNAL((stderr, "/running deferred handler %p\n", pending_handler));
- (*pending_handler)(data->pending_signal,&(data->pending_info), v_context);
+ (*pending_handler)(data->pending_signal,&(data->pending_info), context);
}
#ifndef LISP_FEATURE_WIN32
/* This function must not cons, because that may trigger a GC. */
void
-sig_stop_for_gc_handler(int signal, siginfo_t *info, void *void_context)
+sig_stop_for_gc_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
-
struct thread *thread=arch_os_get_current_thread();
sigset_t ss;
sigemptyset(&unblock);
sigaddset(&unblock, signal);
thread_sigmask(SIG_UNBLOCK, &unblock, 0);
- (*interrupt_low_level_handlers[signal])(signal, info, void_context);
+ (*interrupt_low_level_handlers[signal])(signal, info, context);
RESTORE_ERRNO;
}
low_level_handle_now_handler(int signal, siginfo_t *info, void *void_context)
{
SAVE_ERRNO(context,void_context);
- (*interrupt_low_level_handlers[signal])(signal, info, void_context);
+ (*interrupt_low_level_handlers[signal])(signal, info, context);
RESTORE_ERRNO;
}
}
if (ARE_SAME_HANDLER(handler, SIG_DFL))
- sa.sa_sigaction = handler;
+ sa.sa_sigaction = (void (*)(int, siginfo_t*, void*))handler;
else if (sigismember(&deferrable_sigset,signal))
sa.sa_sigaction = low_level_maybe_now_maybe_later;
- /* The use of a trampoline appears to break the
- arch_os_get_context() workaround for SPARC/Linux. For now,
- don't use the trampoline (and so be vulnerable to the problems
- that SA_NODEFER is meant to solve. */
-#if !(defined(LISP_FEATURE_SPARC) && defined(LISP_FEATURE_LINUX))
else if (!sigaction_nodefer_works &&
!sigismember(&blockable_sigset, signal))
sa.sa_sigaction = low_level_unblock_me_trampoline;
-#endif
else
sa.sa_sigaction = low_level_handle_now_handler;
/* This is called from Lisp. */
unsigned long
-install_handler(int signal, void handler(int, siginfo_t*, void*))
+install_handler(int signal, void handler(int, siginfo_t*, os_context_t*))
{
#ifndef LISP_FEATURE_WIN32
struct sigaction sa;
if (interrupt_low_level_handlers[signal]==0) {
if (ARE_SAME_HANDLER(handler, SIG_DFL) ||
ARE_SAME_HANDLER(handler, SIG_IGN))
- sa.sa_sigaction = handler;
+ sa.sa_sigaction = (void (*)(int, siginfo_t*, void*))handler;
else if (sigismember(&deferrable_sigset, signal))
sa.sa_sigaction = maybe_now_maybe_later;
else if (!sigaction_nodefer_works &&
/* This must not go through lisp as it's allowed anytime, even when on
* the altstack. */
void
-sigabrt_handler(int signal, siginfo_t *info, void *void_context)
+sigabrt_handler(int signal, siginfo_t *info, os_context_t *context)
{
lose("SIGABRT received.\n");
}
* signal(..)-style one-argument handlers, which is OK
* because it works to call the 1-argument form where the
* 3-argument form is expected.) */
- (void (*)(int, siginfo_t*, void*))SIG_DFL;
+ (void (*)(int, siginfo_t*, os_context_t*))SIG_DFL;
}
undoably_install_low_level_interrupt_handler(SIGABRT, sigabrt_handler);
SHOW("returning from interrupt_init()");
union interrupt_handler {
lispobj lisp;
- void (*c)(int, siginfo_t*, void*);
+ void (*c)(int, siginfo_t*, os_context_t*);
};
extern union interrupt_handler interrupt_handlers[NSIG];
struct interrupt_data {
/* signal information for pending signal. pending_signal=0 when there
* is no pending signal. */
- void (*pending_handler) (int, siginfo_t*, void*) ;
+ void (*pending_handler) (int, siginfo_t*, os_context_t*) ;
int pending_signal;
siginfo_t pending_info;
sigset_t pending_mask;
#endif
#ifdef LISP_FEATURE_SB_THREAD
-extern void sig_stop_for_gc_handler(int, siginfo_t*, void*);
+extern void sig_stop_for_gc_handler(int, siginfo_t*, os_context_t*);
#endif
-typedef void (*interrupt_handler_t)(int, siginfo_t *, void *);
+typedef void (*interrupt_handler_t)(int, siginfo_t *, os_context_t *);
extern void undoably_install_low_level_interrupt_handler (
int signal,
interrupt_handler_t handler);
* page fault on this OS.
*/
static void
-sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
os_vm_address_t addr = arch_get_bad_addr(signal, info, context);
#ifdef LISP_FEATURE_ALPHA
}
static void
-sigtrap_handler(int signal, siginfo_t *info, void *void_context)
+sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int code = (os_context_insn(context) >> 6) & 0xfffff;
/* FIXME: This magic number is pseudo-atomic-trap from parms.lisp.
* Genesis should provide the proper #define, but it specialcases
#define FIXNUM_VALUE(lispobj) (((int)lispobj) >> N_FIXNUM_TAG_BITS)
static void
-sigfpe_handler(int signal, siginfo_t *info, void *void_context)
+sigfpe_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int bad_inst = os_context_insn(context);
unsigned int op, rs, rt, rd, funct, dest = 32;
int immed;
static void
-sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
-
os_vm_address_t addr = arch_get_bad_addr(signal,info,context);
if (addr != NULL &&
}
static void
-sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context)
+sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
unsigned int code;
- os_context_t *context = void_context;
code=*((u32 *)(*os_context_pc_addr(context)));
if (code == ((3 << 26) | (0x18 << 21) | (reg_NL3 << 16))) {
\f
/* SIGINT handler that invokes the monitor (for when Lisp isn't up to it) */
static void
-sigint_handler(int signal, siginfo_t *info, void *void_context)
+sigint_handler(int signal, siginfo_t *info, os_context_t *context)
{
lose("\nSIGINT hit at 0x%08lX\n",
- (unsigned long) *os_context_pc_addr(void_context));
+ (unsigned long) *os_context_pc_addr(context));
}
/* (This is not static, because we want to be able to call it from
arch_skip_instruction(context);
}
-static void sigill_handler(int signal, siginfo_t *siginfo, void *void_context)
+static void sigill_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
-
if ((siginfo->si_code) == ILL_ILLOPC
#ifdef LISP_FEATURE_LINUX
|| (linux_sparc_siginfo_bug && (siginfo->si_code == 2))
}
}
-static void sigemt_handler(int signal, siginfo_t *siginfo, void *void_context)
+static void sigemt_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context)
{
unsigned int badinst;
boolean subtract, immed;
int rd, rs1, op1, rs2, op2, result;
- os_context_t *context = arch_os_get_context(&void_context);
badinst = *(unsigned int *)os_context_pc_addr(context);
if ((badinst >> 30) != 2 || ((badinst >> 20) & 0x1f) != 0x11) {
static inline os_context_t *arch_os_get_context(void **void_context)
{
asm volatile ("ta 0x03"); /* ta ST_FLUSH_WINDOWS */
- return (os_context_t *) (void_context + 37);
+ return (os_context_t *) (*void_context);
}
unsigned long os_context_fp_control(os_context_t *context);
#if defined LISP_FEATURE_GENCGC
void
-sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
void* fault_addr = (void*)info->si_addr;
if (!gencgc_handle_wp_violation(fault_addr))
#else
static void
-sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
os_vm_address_t addr = arch_get_bad_addr(signal, info, context);
if (!cheneygc_handle_wp_violation(context, addr)) {
\f
void
-sigtrap_handler(int signal, siginfo_t *info, void *void_context)
+sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = (os_context_t*)void_context;
unsigned int trap;
if (single_stepping && (signal==SIGTRAP))
}
void
-sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = (os_context_t*)void_context;
-
+sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context) {
/* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
* we need to use illegal instructions for traps.
*/
#if defined(LISP_FEATURE_DARWIN) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
if (*((unsigned short *)*os_context_pc_addr(context)) == 0x0b0f) {
*os_context_pc_addr(context) += 2;
- return sigtrap_handler(signal, siginfo, void_context);
+ return sigtrap_handler(signal, siginfo, context);
}
#endif
}
static void
-sigfpe_handler(int signal, siginfo_t *siginfo, void *void_context)
+sigfpe_handler(int signal, siginfo_t *siginfo, os_context_t *context)
{
- os_context_t *context = arch_os_get_context(&void_context);
unsigned int *mxcsr = arch_os_context_mxcsr_addr(context);
if (siginfo->si_code == 0) { /* XMM exception */
kern_return_t mach_thread_init(mach_port_t thread_exception_port);
-void sigill_handler(int signal, siginfo_t *siginfo, void *void_context);
-void sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context);
-void memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context);
+void sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context);
+void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context);
+void memory_fault_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context);
/* exc_server handles mach exception messages from the kernel and
* calls catch exception raise. We use the system-provided
#endif
void
-control_stack_exhausted_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = arch_os_get_context(&void_context);
-
+control_stack_exhausted_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context) {
unblock_signals_in_context_and_maybe_warn(context);
arrange_return_to_lisp_function
(context, StaticSymbolFunction(CONTROL_STACK_EXHAUSTED_ERROR));
}
void
-undefined_alien_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = arch_os_get_context(&void_context);
-
+undefined_alien_handler(int signal, siginfo_t *siginfo, os_context_t *context) {
arrange_return_to_lisp_function
(context, StaticSymbolFunction(UNDEFINED_ALIEN_VARIABLE_ERROR));
}
#ifndef LISP_FEATURE_WIN32
void
-sigtrap_handler(int signal, siginfo_t *info, void *void_context)
+sigtrap_handler(int signal, siginfo_t *info, os_context_t *context)
{
- os_context_t *context = (os_context_t*)void_context;
unsigned int trap;
if (single_stepping && (signal==SIGTRAP)) {
}
void
-sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = (os_context_t*)void_context;
-
+sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context) {
/* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
* we need to use illegal instructions for traps.
*/
#if defined(LISP_FEATURE_DARWIN) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
if (*((unsigned short *)*os_context_pc_addr(context)) == 0x0b0f) {
*os_context_pc_addr(context) += 2;
- return sigtrap_handler(signal, siginfo, void_context);
+ return sigtrap_handler(signal, siginfo, context);
}
#endif
fake_foreign_function_call(context);
#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
-void sigill_handler(int signal, siginfo_t *siginfo, void *void_context);
-void sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context);
-void memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context);
+void sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context);
+void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context);
+void memory_fault_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context);
/* exc_server handles mach exception messages from the kernel and
* calls catch exception raise. We use the system-provided
#endif
void
-control_stack_exhausted_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = arch_os_get_context(&void_context);
+control_stack_exhausted_handler(int signal, siginfo_t *siginfo,
+ os_context_t *context) {
unblock_signals_in_context_and_maybe_warn(context);
arrange_return_to_lisp_function
}
void
-undefined_alien_handler(int signal, siginfo_t *siginfo, void *void_context) {
- os_context_t *context = arch_os_get_context(&void_context);
-
+undefined_alien_handler(int signal, siginfo_t *siginfo, os_context_t *context) {
arrange_return_to_lisp_function
(context, StaticSymbolFunction(UNDEFINED_ALIEN_VARIABLE_ERROR));
}
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.25.53"
+"1.0.25.54"