- ECL accepts FTYPE proclamations for SETF-functions.
+ - On platforms where a stack overflow does not cause a SIGSEGV, ECL was unable
+ to recover from it. Now it jumps to the outermost protection frame
+ (typically the toplevel).
+
* Visible changes:
- Significant speedup in access to hash tables of up to 30% by writing
abort();
}
+
+void
+ecl_unrecoverable_error(cl_env_ptr the_env, const char *message)
+{
+ /*
+ * Right now we have no means of specifying a jump point
+ * for really bad events. We just jump to the outermost
+ * frame, which is equivalent to quitting, and wait for
+ * someone to intercept this jump.
+ */
+ ecl_frame_ptr destination;
+ cl_object tag;
+
+ /*
+ * We output the error message with very low level routines
+ * because we can not risk another stack overflow.
+ */
+ writestr_stream(message, cl_core.error_output);
+
+ tag = ECL_SYM_VAL(the_env, @'si::*quit-tag*');
+ the_env->nvalues = 0;
+ if (tag) {
+ destination = frs_sch(tag);
+ if (destination) {
+ ecl_unwind(the_env, destination);
+ }
+ }
+ destination = ecl_process_env()->frs_org;
+ ecl_unwind(the_env, destination);
+}
+
/*****************************************************************************/
/* Support for Lisp Error Handler */
/*****************************************************************************/
void
ecl_cs_overflow(void)
{
+ static const char *stack_overflow_msg =
+ "\n;;;\n;;; Stack overflow.\n"
+ ";;; Jumping to the outermost toplevel prompt\n"
+ ";;;\n\n";
cl_env_ptr env = ecl_process_env();
cl_index safety_area = ecl_get_option(ECL_OPT_C_STACK_SAFETY_AREA);
cl_index size = env->cs_size;
env->cs_limit += safety_area;
#endif
else
- ecl_internal_error("Cannot grow stack size.");
+ ecl_unrecoverable_error(env, stack_overflow_msg);
cl_cerror(6, make_constant_base_string("Extend stack size"),
@'ext::stack-overflow', @':size', MAKE_FIXNUM(size),
@':type', @'ext::c-stack');
ecl_symbol_value(@'si::*interrupts-enabled*') == Cnil);
}
-static void
-jump_to_sigsegv_handler(cl_env_ptr the_env, const char *message)
-{
- /*
- * Right now we have no means of specifying a jump point
- * for really bad events. We just jump to the outermost
- * frame, which is equivalent to quitting, and wait for
- * someone to intercept this jump.
- */
- ecl_frame_ptr destination;
- cl_object tag;
-
- /*
- * We output the error message with very low level routines
- * because we can not risk another stack overflow.
- */
- writestr_stream(message, cl_core.error_output);
-
- tag = ECL_SYM_VAL(the_env, @'si::*quit-tag*');
- the_env->nvalues = 0;
- if (tag) {
- destination = frs_sch(tag);
- if (destination) {
- ecl_unwind(the_env, destination);
- }
- }
- destination = ecl_process_env()->frs_org;
- ecl_unwind(the_env, destination);
-}
-
static cl_object pop_signal(cl_env_ptr env);
static cl_object
if ((char*)info->si_addr > the_env->cs_barrier &&
(char*)info->si_addr <= the_env->cs_org) {
unblock_signal(SIGSEGV);
- jump_to_sigsegv_handler(the_env, stack_overflow_msg);
+ ecl_unrecoverable_error(the_env, stack_overflow_msg);
return;
}
# else
if ((char*)info->si_addr < the_env->cs_barrier &&
(char*)info->si_addr >= the_env->cs_org) {
unblock_signal(SIGSEGV);
- jump_to_sigsegv_handler(the_env, stack_overflow_msg);
+ ecl_unrecoverable_error(the_env, stack_overflow_msg);
return;
}
# endif
* up to the outermost toplevel.
*/
unblock_signal(SIGSEGV);
- jump_to_sigsegv_handler(the_env, segv_msg);
+ ecl_unrecoverable_error(the_env, segv_msg);
# else
handle_or_queue(@'ext::segmentation-violation', SIGSEGV);
# endif
* the outermost handler.
*/
unblock_signal(SIGSEGV);
- jump_to_sigsegv_handler(the_env, segv_msg);
+ ecl_unrecoverable_error(the_env, segv_msg);
#endif
}
extern ECL_API cl_object cl_error _ARGS((cl_narg narg, cl_object eformat, ...)) ecl_attr_noreturn;
extern ECL_API cl_object cl_cerror _ARGS((cl_narg narg, cl_object cformat, cl_object eformat, ...));
-extern ECL_API void ecl_internal_error(const char *s) /*ecl_attr_noreturn*/;
+extern ECL_API void ecl_internal_error(const char *s) ecl_attr_noreturn;
+extern ECL_API void ecl_unrecoverable_error(cl_env_ptr the_env, const char *message) ecl_attr_noreturn;
extern ECL_API void ecl_cs_overflow(void) /*ecl_attr_noreturn*/;
extern ECL_API void FEprogram_error(const char *s, int narg, ...) ecl_attr_noreturn;
extern ECL_API void FEprogram_error_noreturn(const char *s, int narg, ...) ecl_attr_noreturn;