mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-15 13:52:16 -08:00
Avoid nested SIGSEGV/BUS interrupts, aborting immediately when it happens
This commit is contained in:
parent
8d1c35daeb
commit
840f041179
3 changed files with 37 additions and 15 deletions
|
|
@ -175,6 +175,7 @@ ecl_init_env(cl_env_ptr env)
|
|||
|
||||
env->packages_to_be_created = Cnil;
|
||||
env->packages_to_be_created_p = Cnil;
|
||||
env->fault_address = env;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -571,14 +571,12 @@ handler_fn_protype(sigsegv_handler, int sig, siginfo_t *info, void *aux)
|
|||
"\n;;;\n;;; Stack overflow.\n"
|
||||
";;; Jumping to the outermost toplevel prompt\n"
|
||||
";;;\n\n";
|
||||
#ifndef HAVE_SIGPROCMASK
|
||||
static const char *segv_msg =
|
||||
"\n;;;\n"
|
||||
";;; Detected access to protected memory, "
|
||||
"also kwown as 'segmentation fault'.\n"
|
||||
";;; Jumping to the outermost toplevel prompt\n"
|
||||
";;;\n\n";
|
||||
#endif
|
||||
cl_env_ptr the_env;
|
||||
reinstall_signal(sig, sigsegv_handler);
|
||||
if (!ecl_option_values[ECL_OPT_BOOTED]) {
|
||||
|
|
@ -622,16 +620,16 @@ handler_fn_protype(sigsegv_handler, int sig, siginfo_t *info, void *aux)
|
|||
return;
|
||||
}
|
||||
# endif
|
||||
# if 0 && defined(SA_ONSTACK)
|
||||
/* The handler is executed in an externally allocated stack, and
|
||||
* thus it is not safe to execute lisp code here. We just bounce
|
||||
* up to the outermost toplevel.
|
||||
*/
|
||||
unblock_signal(the_env, SIGSEGV);
|
||||
ecl_unrecoverable_error(the_env, segv_msg);
|
||||
# else
|
||||
handle_or_queue(the_env, @'ext::segmentation-violation', SIGSEGV);
|
||||
# endif
|
||||
/* Do not attempt an error handler if we nest two serious
|
||||
* errors in the same thread */
|
||||
if (the_env->fault_address == info->si_addr) {
|
||||
the_env->fault_address = info->si_addr;
|
||||
unblock_signal(the_env, SIGSEGV);
|
||||
ecl_unrecoverable_error(the_env, segv_msg);
|
||||
} else {
|
||||
the_env->fault_address = info->si_addr;
|
||||
handle_or_queue(the_env, @'ext::segmentation-violation', SIGSEGV);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* We cannot distinguish between a stack overflow and a simple
|
||||
|
|
@ -647,13 +645,20 @@ handler_fn_protype(sigsegv_handler, int sig, siginfo_t *info, void *aux)
|
|||
static void
|
||||
handler_fn_protype(sigbus_handler, int sig, siginfo_t *info, void *aux)
|
||||
{
|
||||
static const char *sigbus_msg =
|
||||
"\n;;;\n"
|
||||
";;; Detected access to invalid or protected memory, "
|
||||
"also kwown as 'SIGBUS'.\n"
|
||||
";;; Jumping to the outermost toplevel prompt\n"
|
||||
";;;\n\n";
|
||||
cl_env_ptr the_env;
|
||||
reinstall_signal(sig, sigsegv_handler);
|
||||
/* The lisp environment might not be installed. */
|
||||
the_env = ecl_process_env();
|
||||
if (zombie_process(the_env))
|
||||
return;
|
||||
#if defined(SA_SIGINFO) && defined(ECL_USE_MPROTECT)
|
||||
#if defined(SA_SIGINFO)
|
||||
# if defined(ECL_USE_MPROTECT)
|
||||
/* We access the environment when it was protected. That
|
||||
* means there was a pending signal. */
|
||||
if (((char*)the_env <= (char*)info->si_addr) &&
|
||||
|
|
@ -669,8 +674,20 @@ handler_fn_protype(sigbus_handler, int sig, siginfo_t *info, void *aux)
|
|||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
handle_or_queue(the_env, @'ext::segmentation-violation', SIGBUS);
|
||||
# endif /* ECL_USE_MPROTECT */
|
||||
/* Do not attempt an error handler if we nest two serious
|
||||
* errors in the same thread */
|
||||
if (the_env->fault_address == info->si_addr) {
|
||||
the_env->fault_address = info->si_addr;
|
||||
unblock_signal(the_env, SIGBUS);
|
||||
ecl_unrecoverable_error(the_env, sigbus_msg);
|
||||
} else {
|
||||
the_env->fault_address = info->si_addr;
|
||||
handle_or_queue(the_env, @'ext::segmentation-violation', SIGSEGV);
|
||||
}
|
||||
#endif /* SA_SIGINFO */
|
||||
unblock_signal(the_env, SIGBUS);
|
||||
ecl_unrecoverable_error(the_env, sigbus_msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,9 @@ struct cl_env_struct {
|
|||
* to be explicitely created by the compiled code itself. */
|
||||
cl_object packages_to_be_created;
|
||||
cl_object packages_to_be_created_p;
|
||||
|
||||
/* Segmentation fault address */
|
||||
void *fault_address;
|
||||
};
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
|
@ -1758,6 +1761,7 @@ extern ECL_API cl_object mp_mailbox_send(cl_object mailbox, cl_object msg);
|
|||
|
||||
extern ECL_API cl_object ecl_atomic_get(cl_object *slot);
|
||||
extern ECL_API void ecl_atomic_push(cl_object *slot, cl_object o);
|
||||
extern ECL_API void ecl_atomic_nconc(cl_object l, cl_object *slot);
|
||||
extern ECL_API cl_object ecl_atomic_pop(cl_object *slot);
|
||||
extern ECL_API cl_index ecl_atomic_index_incf(cl_index *slot);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue