diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index 811624381..3f7b993df 100755 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -1847,6 +1847,7 @@ cl_symbols[] = { {EXT_ "LISP-STACK", EXT_ORDINARY, NULL, -1, OBJNULL}, {EXT_ "C-STACK", EXT_ORDINARY, NULL, -1, OBJNULL}, {EXT_ "HEAP-SIZE", EXT_ORDINARY, NULL, -1, OBJNULL}, +{EXT_ "ILLEGAL-INSTRUCTION", EXT_ORDINARY, NULL, -1, OBJNULL}, {EXT_ "SET-LIMIT", EXT_ORDINARY, si_set_limit, 2, OBJNULL}, {EXT_ "GET-LIMIT", EXT_ORDINARY, si_get_limit, 1, OBJNULL}, {EXT_ "SEGMENTATION-VIOLATION", EXT_ORDINARY, NULL, -1, OBJNULL}, diff --git a/src/c/symbols_list2.h b/src/c/symbols_list2.h index 42052a18e..a0773b1a3 100644 --- a/src/c/symbols_list2.h +++ b/src/c/symbols_list2.h @@ -1847,6 +1847,7 @@ cl_symbols[] = { {EXT_ "LISP-STACK",NULL}, {EXT_ "C-STACK",NULL}, {EXT_ "HEAP-SIZE",NULL}, +{EXT_ "ILLEGAL-INSTRUCTION",NULL}, {EXT_ "SET-LIMIT","si_set_limit"}, {EXT_ "GET-LIMIT","si_get_limit"}, {EXT_ "SEGMENTATION-VIOLATION",NULL}, diff --git a/src/c/unixint.d b/src/c/unixint.d index d2cea00ff..0310a5e4e 100644 --- a/src/c/unixint.d +++ b/src/c/unixint.d @@ -362,6 +362,10 @@ handler_fn_protype(lisp_signal_handler, int sig, siginfo_t *info, void *aux) case SIGBUS: return @'ext::segmentation-violation'; #endif +#ifdef SIGILL + case SIGILL: + return @'ext::illegal-instruction'; +#endif #ifdef SIGCHLD case SIGCHLD: return SYM_FUN(@'si::wait-for-all-processes'); @@ -845,21 +849,21 @@ ecl_interrupt_process(cl_object process, cl_object function) * - In POSIX systems it sends a user level interrupt to * the thread, which then decides how to act. */ - /* Trivial spinlock to ensure that the process is past - * the section where it establishes a CATCH */ - while (process->process.phase == ECL_PROCESS_BOOTING) - ecl_musleep(0.0, 0); - /* And then only care when the process is really active, for - * otherwise the signal will be ignored. */ - if (process->process.phase == ECL_PROCESS_ACTIVE) { - /* If FUNCTION is NIL, we just intend to wake up the - * process from some call to ecl_musleep() */ - if (!Null(function)) { + if (!Null(function)) { + /* Trivial spinlock to ensure that the process is past + * the section where it establishes a CATCH */ + while (process->process.phase == ECL_PROCESS_BOOTING) + ecl_musleep(0.0, 0); + /* And then only care when the process is really active, for + * otherwise the signal will be ignored. */ + if (process->process.phase == ECL_PROCESS_ACTIVE) { + /* If FUNCTION is NIL, we just intend to wake up the + * process from some call to ecl_musleep() */ function = si_coerce_to_function(function); queue_signal(process->process.env, function); } - do_interrupt_thread(process); } + do_interrupt_thread(process); } #endif /* ECL_THREADS */ @@ -920,7 +924,7 @@ _ecl_w32_exception_filter(struct _EXCEPTION_POINTERS* ep) return EXCEPTION_CONTINUE_EXECUTION; /* Catch illegal instruction */ case EXCEPTION_ILLEGAL_INSTRUCTION: - handle_or_queue(MAKE_FIXNUM(SIGILL), 0); + handle_or_queue(@'ext::illegal-instruction', 0); return EXCEPTION_CONTINUE_EXECUTION; /* Do not catch anything else */ default: @@ -1207,6 +1211,11 @@ install_synchronous_signal_handlers() mysignal(SIGPIPE, non_evil_signal_handler); } #endif +#ifdef SIGILL + if (ecl_get_option(ECL_OPT_TRAP_SIGILL)) { + mysignal(SIGILL, non_evil_signal_handler); + } +#endif } /* diff --git a/src/clos/conditions.lsp b/src/clos/conditions.lsp index 4220316ee..bd152be78 100644 --- a/src/clos/conditions.lsp +++ b/src/clos/conditions.lsp @@ -511,6 +511,10 @@ or return to an outer frame, undoing all the function calls so far." (:REPORT "Memory limit reached. Please jump to an outer pointer, quit program and enlarge the memory limits before executing the program again.")) +(define-condition ext:illegal-instruction (serious-condition) + () + (:REPORT "Illegal instruction.")) + (define-condition ext:unix-signal-received () ((code :type fixnum :initform 0