siginfo_t *info,
os_context_t *context);
+static void
+fill_current_sigmask(sigset_t *sigset)
+{
+ /* Get the current sigmask, by blocking the empty set. */
+ sigset_t empty;
+ sigemptyset(&empty);
+ thread_sigmask(SIG_BLOCK, &empty, sigset);
+}
+
void
sigaddset_deferrable(sigset_t *s)
{
sigaddset(s, SIGHUP);
sigaddset(s, SIGINT);
+ sigaddset(s, SIGTERM);
sigaddset(s, SIGQUIT);
sigaddset(s, SIGPIPE);
sigaddset(s, SIGALRM);
}
/* initialized in interrupt_init */
-static sigset_t deferrable_sigset;
-static sigset_t blockable_sigset;
+sigset_t deferrable_sigset;
+sigset_t blockable_sigset;
+#endif
+
+void
+check_deferrables_blocked_in_sigset_or_lose(sigset_t *sigset)
+{
+#if !defined(LISP_FEATURE_WIN32)
+ int i;
+ for(i = 1; i < NSIG; i++) {
+ if (sigismember(&deferrable_sigset, i) && !sigismember(sigset, i))
+ lose("deferrable signal %d not blocked\n",i);
+ }
+#endif
+}
+
+void
+check_deferrables_blocked_or_lose(void)
+{
+#if !defined(LISP_FEATURE_WIN32)
+ sigset_t current;
+ fill_current_sigmask(¤t);
+ check_deferrables_blocked_in_sigset_or_lose(¤t);
#endif
+}
void
check_blockables_blocked_or_lose(void)
struct thread *thread;
- /* Punt if in PA section, marking it as interrupted. This can
- * happenat least if we pick up a GC request while in a
- * WITHOUT-GCING with an outer PA -- it is not immediately clear
- * to me that this should/could ever happen, but better safe then
- * sorry. --NS 2007-05-15 */
if (arch_pseudo_atomic_atomic(context)) {
- arch_set_pseudo_atomic_interrupted(context);
- return;
+ lose("Handling pending interrupt in pseduo atomic.");
}
thread = arch_os_get_current_thread();
store_signal_data_for_later(data,handler,signal,info,context);
SetSymbolValue(INTERRUPT_PENDING, T,thread);
FSHOW_SIGNAL((stderr,
- "/maybe_defer_handler(%x,%d),thread=%lu: deferred\n",
- (unsigned int)handler,signal,
- (unsigned long)thread->os_thread));
+ "/maybe_defer_handler(%x,%d): deferred\n",
+ (unsigned int)handler,signal));
return 1;
}
/* a slightly confusing test. arch_pseudo_atomic_atomic() doesn't
store_signal_data_for_later(data,handler,signal,info,context);
arch_set_pseudo_atomic_interrupted(context);
FSHOW_SIGNAL((stderr,
- "/maybe_defer_handler(%x,%d),thread=%lu: deferred(PA)\n",
- (unsigned int)handler,signal,
- (unsigned long)thread->os_thread));
+ "/maybe_defer_handler(%x,%d): deferred(PA)\n",
+ (unsigned int)handler,signal));
return 1;
}
FSHOW_SIGNAL((stderr,
- "/maybe_defer_handler(%x,%d),thread=%lu: not deferred\n",
- (unsigned int)handler,signal,
- (unsigned long)thread->os_thread));
+ "/maybe_defer_handler(%x,%d): not deferred\n",
+ (unsigned int)handler,signal));
return 0;
}
if (arch_pseudo_atomic_atomic(context)) {
SetSymbolValue(STOP_FOR_GC_PENDING,T,thread);
arch_set_pseudo_atomic_interrupted(context);
- FSHOW_SIGNAL((stderr,"thread=%lu sig_stop_for_gc deferred (PA)\n",
- thread->os_thread));
+ FSHOW_SIGNAL((stderr, "sig_stop_for_gc deferred (PA)\n"));
return;
}
else if (SymbolValue(GC_INHIBIT,thread) != NIL) {
SetSymbolValue(STOP_FOR_GC_PENDING,T,thread);
- FSHOW_SIGNAL((stderr,
- "thread=%lu sig_stop_for_gc deferred (*GC-INHIBIT*)\n",
- thread->os_thread));
+ FSHOW_SIGNAL((stderr, "sig_stop_for_gc deferred (*GC-INHIBIT*)\n"));
return;
}
}
thread->state=STATE_SUSPENDED;
- FSHOW_SIGNAL((stderr,"thread=%lu suspended\n",thread->os_thread));
+ FSHOW_SIGNAL((stderr,"suspended\n"));
sigemptyset(&ss);
#if defined(SIG_RESUME_FROM_GC)
while (sigwaitinfo(&ss,0) != SIG_STOP_FOR_GC);
#endif
- FSHOW_SIGNAL((stderr,"thread=%lu resumed\n",thread->os_thread));
+ FSHOW_SIGNAL((stderr,"resumed\n"));
if(thread->state!=STATE_RUNNING) {
lose("sig_stop_for_gc_handler: wrong thread state on wakeup: %ld\n",
fixnum_value(thread->state));
os_context_t *context = arch_os_get_context(&void_context);
#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
os_restore_fp_control(context);
+#ifndef LISP_FEATURE_WIN32
+ if ((signal == SIGILL) || (signal == SIGBUS)
+#ifndef LISP_FEATURE_LINUX
+ || (signal == SIGEMT)
+#endif
+ )
+ corruption_warning_and_maybe_lose("Signal %d recieved", signal);
+#endif
#endif
interrupt_handle_now(signal, info, context);
}
*os_context_register_addr(context,reg_CODE) =
(os_context_register_t)(fun + FUN_POINTER_LOWTAG);
#endif
+ FSHOW((stderr, "/arranged return to Lisp function (0x%lx)\n",
+ (long)function));
}
#ifdef LISP_FEATURE_SB_THREAD
{
os_context_t *context = (os_context_t*)arch_os_get_context(&v_context);
+ FSHOW_SIGNAL((stderr,"/interrupt_thread_handler\n"));
+ check_blockables_blocked_or_lose();
+
/* let the handler enable interrupts again when it sees fit */
sigaddset_deferrable(os_context_sigmask_addr(context));
arrange_return_to_lisp_function(context,
* protection so the error handler has some headroom, protect the
* previous page so that we can catch returns from the guard page
* and restore it. */
+ corruption_warning_and_maybe_lose("Control stack exhausted");
protect_control_stack_guard_page(0);
protect_control_stack_return_guard_page(1);
#endif
}
+/* 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)
+{
+ lose("SIGABRT received.\n");
+}
+
void
interrupt_init(void)
{
* 3-argument form is expected.) */
(void (*)(int, siginfo_t*, void*))SIG_DFL;
}
-
+ undoably_install_low_level_interrupt_handler(SIGABRT, sigabrt_handler);
SHOW("returning from interrupt_init()");
#endif
}
* now -- some address is better then no address in this case.
*/
current_memory_fault_address = addr;
+ /* To allow debugging memory faults in signal handlers and such. */
+ corruption_warning_and_maybe_lose("Memory fault");
arrange_return_to_lisp_function(context,
StaticSymbolFunction(MEMORY_FAULT_ERROR));
}