diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-07-06 06:01:01 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-07-06 06:01:01 -0700 |
commit | 7a926eb8da998fba873900fadc4f2fa179e7319f (patch) | |
tree | 67617f9cf2c4cb0bedc03c70d6c82da0d6a92a67 /unwind.c | |
parent | da442bbb28b7df94d730aba0ed46064ff2ffd9cb (diff) | |
download | txr-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.c | 16 |
1 files changed, 8 insertions, 8 deletions
@@ -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); } } |