Handle SIGILL.

This commit is contained in:
Juan Jose Garcia Ripoll 2012-03-29 12:43:50 +02:00
parent 76de423dcd
commit 4bbeaa8f6e
4 changed files with 27 additions and 12 deletions

View file

@ -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},

View file

@ -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},

View file

@ -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
}
/*

View file

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