From 05f01eeac89abd78d5d16c04bf31f0b1b0076213 Mon Sep 17 00:00:00 2001 From: Christophe Rhodes Date: Wed, 24 Jul 2002 10:43:17 +0000 Subject: [PATCH] 0.7.6.4: SPARC fixups ... make DB's wonderful stack exhaustion work on the SPARC adjust NPC logic add in fixup for bizarre SPARC calling convention ... improve signal handling on SPARC/Linux make a distinction between interrupt_handle_now() as called from handlers, and interrupt_handle_now_handler() installed as the sa_sigaction bit. --- BUGS | 6 ----- NEWS | 3 +++ src/runtime/interrupt.c | 59 ++++++++++++++++++++++++++++++++--------------- version.lisp-expr | 2 +- 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/BUGS b/BUGS index 3321811..58bd328 100644 --- a/BUGS +++ b/BUGS @@ -1319,12 +1319,6 @@ WORKAROUND: the compiler handle the error, convert it into a COMPILER-ERROR, and continue compiling) which seems wrong. -182: "SPARC/Linux floating point" - Evaluating (/ 1.0 0.0) at the prompt causes a Bus error and complete - death of the environment. Other floating point operations sometimes - return infinities when they should raise traps (e.g. the test case - for bug #146, (expt 2.0 12777)). - 183: "IEEE floating point issues" Even where floating point handling is being dealt with relatively well (as of sbcl-0.7.5, on sparc/sunos and alpha; see bug #146), the diff --git a/NEWS b/NEWS index eab5231..007ccd9 100644 --- a/NEWS +++ b/NEWS @@ -1196,6 +1196,9 @@ changes in sbcl-0.7.7 relative to sbcl-0.7.6: suppressed.) Also now that the compiler is looking at declarations in the environment, it checks optimization declarations as well, and suppresses inlining when (> DEBUG SPEED). + * More fixes have been made to treatment of floating point exception + treatment and other Unix signals. In particular, floating point + exceptions no longer cause Bus errors on the SPARC/Linux platform. planned incompatible changes in 0.7.x: * When the profiling interface settles down, maybe in 0.7.x, maybe diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index feb2cc9..da023bf 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -342,6 +342,15 @@ interrupt_handle_pending(os_context_t *context) * 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 @@ -354,9 +363,9 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) union interrupt_handler handler; #ifdef LISP_FEATURE_LINUX - /* Under Linux, we appear to have to restore the fpu control word - from the context, as after the signal is delivered we appear to - have a null fpu control word. */ + /* Under Linux on some architectures, we appear to have to restore + the FPU control word from the context, as after the signal is + delivered we appear to have a null FPU control word. */ os_restore_fp_control(context); #endif handler = interrupt_handlers[signal]; @@ -434,15 +443,8 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) static void maybe_now_maybe_later(int signal, siginfo_t *info, void *void_context) { - os_context_t *context = (os_context_t*)void_context; + os_context_t *context = arch_os_get_context(&void_context); - /* FIXME: See Debian cmucl 2.4.17, and mail from DTC on the CMU CL - * mailing list 23 Oct 1999, for changes in FPU handling at - * interrupt time which should be ported into SBCL. Also see the - * analogous logic at the head of interrupt_handle_now for - * more related FIXME stuff. - */ - #ifdef LISP_FEATURE_LINUX os_restore_fp_control(context); #endif @@ -488,6 +490,14 @@ maybe_now_maybe_later(int signal, siginfo_t *info, void *void_context) } } + +void +interrupt_handle_now_handler(int signal, siginfo_t *info, void *void_context) +{ + os_context_t *context = arch_os_get_context(&void_context); + interrupt_handle_now(signal, info, context); +} + /* * stuff to detect and handle hitting the GC trigger */ @@ -528,18 +538,31 @@ boolean handle_control_stack_guard_triggered(os_context_t *context,void *addr) * user's backtrace makes (as much) sense (as usual) */ build_fake_control_stack_frames(context); /* signal handler will "return" to this error-causing function */ - *os_context_pc_addr(context)= function; + *os_context_pc_addr(context) = function; #ifndef LISP_FEATURE_X86 /* this much of the calling convention is common to all non-x86 ports */ - *os_context_register_addr(context,reg_NARGS)=0; - *os_context_register_addr(context,reg_LIP)= function; - *os_context_register_addr(context,reg_CFP)= + *os_context_register_addr(context,reg_NARGS) = 0; + *os_context_register_addr(context,reg_LIP) = function; + *os_context_register_addr(context,reg_CFP) = current_control_frame_pointer; +#endif #ifdef ARCH_HAS_NPC_REGISTER - *os_context_register_addr(context,reg_LIP)= - 4+*os_context_pc_addr(context); + *os_context_npc_addr(context) = + 4 + *os_context_pc_addr(context); #endif +#ifdef LISP_FEATURE_SPARC + /* Bletch. This is a feature of the SPARC calling convention, + which sadly I'm not going to go into in large detail here, + as I don't know it well enough. Suffice to say that if the + line + + (INST MOVE CODE-TN FUNCTION) + + in compiler/sparc/call.lisp is changed, then this bit can + probably go away. -- CSR, 2002-07-24 */ + *os_context_register_addr(context,reg_CODE) = + function - SIMPLE_FUN_CODE_OFFSET; #endif return 1; } @@ -720,7 +743,7 @@ install_handler(int signal, void handler(int, siginfo_t*, void*)) } else if (sigismember(&new, signal)) { sa.sa_sigaction = maybe_now_maybe_later; } else { - sa.sa_sigaction = interrupt_handle_now; + sa.sa_sigaction = interrupt_handle_now_handler; } sigemptyset(&sa.sa_mask); diff --git a/version.lisp-expr b/version.lisp-expr index f6bf2b5..fe432d1 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -18,4 +18,4 @@ ;;; for internal versions, especially for internal versions off the ;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.7.6.3" +"0.7.6.4" -- 1.7.10.4