summaryrefslogtreecommitdiffstats
path: root/unwind.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-16 01:52:56 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-16 01:52:56 -0800
commit83778347170b3168bbfd5a87bad1eb12700f5cd0 (patch)
tree9af5a9c884ab7834519e6650022d763f8415bb62 /unwind.c
parentb68fb2aad15663edfe7c3671c97bd85bc531c565 (diff)
downloadtxr-83778347170b3168bbfd5a87bad1eb12700f5cd0.tar.gz
txr-83778347170b3168bbfd5a87bad1eb12700f5cd0.tar.bz2
txr-83778347170b3168bbfd5a87bad1eb12700f5cd0.zip
In the spirit of the previous hack, here is another hack to
alleviate a long-standing pain: when an exception happens in TXR's library somewhere, the program dies without leaving a clue about what code was being evaluated when that happened. What we can do is have the evaluator publish the most recent compound form it has processed by stashing it in a variable. Then when an unhandled exception occurs, we can peek at that and try to pull out source location info. * eval.c (last_form_evaled): New variable. (do_eval): When evaluating a compound form, stash it in last_form_evaled. (eval_init): Protect last_form_evaled from gc. * eval.h (last_form_evaled): Declared. (eval_error_s): Existing variable declared. * unwind.c: Has to include "eval.h" for the above variable and "parser.h" for the source_loc function. (uw_throw): When an exception is unhandled, if last_form_evaled has source info, add it to the diagnostic. But not if the exception is eval-error; because errors from the evaluators already have the info.
Diffstat (limited to 'unwind.c')
-rw-r--r--unwind.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/unwind.c b/unwind.c
index f447bb07..fc703fc3 100644
--- a/unwind.c
+++ b/unwind.c
@@ -38,6 +38,8 @@
#include "stream.h"
#include "txr.h"
#include "signal.h"
+#include "eval.h"
+#include "parser.h"
#include "unwind.h"
static uw_frame_t *uw_stack;
@@ -275,10 +277,18 @@ val uw_throw(val sym, val exception)
if (opt_loglevel >= 1) {
val s = stringp(exception);
+ val info = if2(source_loc(last_form_evaled),
+ source_loc_str(last_form_evaled));
format(std_error, lit("~a: unhandled exception of type ~a:\n"),
prog_string, sym, nao);
+
+ if (info && sym != eval_error_s)
+ format(std_error, lit("~a: possibly triggered by ~a\n"),
+ prog_string, info, nao);
+
format(std_error, s ? lit("~a: ~a\n") : lit("~a: ~s\n"),
prog_string, exception, nao);
+
}
if (uw_exception_subtype_p(sym, query_error_s) ||
uw_exception_subtype_p(sym, file_error_s)) {