Gauche
Gauche copied to clipboard
Display additional stack trace for r7rs#import error
#521 の件に対応したものです。
問題がありそうですが、まずは案として挙げておきます。
<原因> r7rs#import は、内部で require を呼んでいる。
require は、内部で Scm_Load を SCM_LOAD_PROPAGATE_ERROR フラグなしで呼んでいる。
Scm_Load は、SCM_LOAD_PROPAGATE_ERROR フラグを指定しないと、 Scm_Apply → safe_eval_wrap → safe_eval_int → Scm_VMWithErrorHandler → with_error_handler と進んで、with_error_handler でエラーをトラップして戻るようになっている。
このエラーをトラップして戻るときに、 Scm_VMDefaultExceptionHandler で vm->cont = ep->cont が実行され、 スタックが巻き戻って、スタックトレースが捨てられている。
<対策> エラーハンドラ (safe_eval_handler) のところで vm->cont を vm->errorCont に保存し、 Scm_DumpStackTrace で追加のスタックトレースを表示するようにした。
表示例.
>gosh -I.
gosh> (import (def))
*** ERROR: invalid application: (() ())
While loading "./def.sld" at line 3
While compiling: (import (def))
While compiling "(windows console standard input)" at line 1: (import (def))
Stack Trace:
_______________________________________
0 (eval expr env)
at "C:\\Program Files (x86)\\Gauche\\share\\gauche-0.97\\0.9.9_pre1\\lib
/gauche/interactive.scm":269
Stack Trace on Error:
_______________________________________
0 (() '())
at "./def.scm":3
1 (case-lambda (() '()) ((lst) lst) ((lst x) (cons x lst)))
at "./def.scm":2
2 (eval expr env)
at "C:\\Program Files (x86)\\Gauche\\share\\gauche-0.97\\0.9.9_pre1\\lib
/gauche/interactive.scm":269
<気になる点> (1) スタックトレースが2個表示されるため、分かりにくい。 (しかし、1個だけ表示すると、だまされるケースが出そう。。。)
(2) vm->errorCont をリセットするよいタイミングがない。 とりあえず safe_eval_wrap と Scm_DumpStackTrace に入れておいたが、 無関係のエラーのときに表示されたりするかも。
(3) safe_eval_handler に save_cont(vm) を追加したため、 速度やメモリ使用量に影響があるかもしれない。 (単に vm->errorCont = vm->cont のみだと SEGV した)
<テスト結果> https://ci.appveyor.com/project/Hamayama/gauche/builds/27558400
2個のスタックトレースが同じ内容だった場合には、 表示しないようにしました。
更新のため、一度クローズします。