summaryrefslogtreecommitdiffstats
path: root/unwind.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-07-06 06:01:01 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-07-06 06:01:01 -0700
commit7a926eb8da998fba873900fadc4f2fa179e7319f (patch)
tree67617f9cf2c4cb0bedc03c70d6c82da0d6a92a67 /unwind.c
parentda442bbb28b7df94d730aba0ed46064ff2ffd9cb (diff)
downloadtxr-7a926eb8da998fba873900fadc4f2fa179e7319f.tar.gz
txr-7a926eb8da998fba873900fadc4f2fa179e7319f.tar.bz2
txr-7a926eb8da998fba873900fadc4f2fa179e7319f.zip
unwind: refer to top-level *stderr* stream.
Exception processing should refer to the original, top-level value of *stderr* rather than the current dynamic value, even if unwinding has not yet taken place. Using the dynamic value can not only cause critical output to disappear, but it leads to a false positive identification of the "unhandled exception in early initialization" situation, a diagnostic which is emitted on the C stderr if the Lisp one is unavailable, which is assumed to be due to initialization not having yet completed. * stream.c (top_stderr): New global variable. (stream_init): GC-protect top_stderr, and initialize it with the same object that goes into the *stderr* top-level binding. * stream.h (top_stderr): Declared. * unwind.c (uw_unwind_to_exit_point, uw_rthrow): Use top_stderr instead of std_error macro.
Diffstat (limited to 'unwind.c')
-rw-r--r--unwind.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/unwind.c b/unwind.c
index 0815a885..60746003 100644
--- a/unwind.c
+++ b/unwind.c
@@ -110,7 +110,7 @@ static void uw_unwind_to_exit_point(void)
case UW_GUARD:
if (uw_stack->gu.uw_ok)
break;
- format(std_error, lit("~a: cannot unwind across foreign stack frames\n"),
+ format(top_stderr, lit("~a: cannot unwind across foreign stack frames\n"),
prog_string, nao);
abort();
default:
@@ -130,11 +130,11 @@ static void uw_unwind_to_exit_point(void)
val prefix = scat2(prog_string, lit(":"));
flush_stream(std_output);
- format(std_error, lit("~a unhandled exception of type ~a:\n"),
+ format(top_stderr, lit("~a unhandled exception of type ~a:\n"),
prefix, sym, nao);
uw_stack = orig_stack;
- error_trace(sym, args, std_error, prefix);
+ error_trace(sym, args, top_stderr, prefix);
}
if (uw_exception_subtype_p(sym, query_error_s) ||
uw_exception_subtype_p(sym, file_error_s)) {
@@ -718,8 +718,8 @@ val uw_rthrow(val sym, val args)
--reentry_count;
if (uw_exception_subtype_p(sym, defr_warning_s))
uw_defer_warning(args);
- else if (std_error != 0)
- format(std_error, lit("~a\n"), car(args), nao);
+ else if (top_stderr != 0)
+ format(top_stderr, lit("~a\n"), car(args), nao);
if (!opt_compat || opt_compat >= 234) {
uw_rthrow(continue_s, nil);
return nil;
@@ -734,7 +734,7 @@ val uw_rthrow(val sym, val args)
}
}
- if (std_error == 0) {
+ if (top_stderr == 0) {
fprintf(stderr, "txr: unhandled exception in early initialization\n");
abort();
}
@@ -749,8 +749,8 @@ val uw_rthrow(val sym, val args)
if (functionp(fun))
funcall3(fun, sym, args, last_form_evaled);
else
- format(std_error, lit("~a: *unhandled-hook* ~s isn't a function\n"),
- prog_string, fun, nao);
+ format(top_stderr, lit("~a: *unhandled-hook* ~s isn't a function\n"),
+ prog_string, fun, nao);
}
}