Skip to content

Commit 5bf9a6f

Browse files
committed
[coq] Enable backtraces on anomaly
This means we will re-execute the anomaly sentence, which may not be very safe. Fixes #153
1 parent 6fafb3d commit 5bf9a6f

File tree

8 files changed

+29
-13
lines changed

8 files changed

+29
-13
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
- Support for OCaml 4.11 (@ejgallego, #184)
55
- The keybinding alt+enter in VSCode is now correctly scoped
66
(@artagnon, #188)
7+
- If a command produces an anomaly, coq-lsp will re-execute it with
8+
stack traces enabled, as to produce a better error report
9+
(@ejgallego, #161, fixes #153)
710

811
# coq-lsp 0.1.3: Event
912
----------------------

coq/init.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,4 @@ let doc_init ~root_state ~workspace ~libname () =
8585
Vernacstate.freeze_interp_state ~marshallable:false |> State.of_coq
8686

8787
let doc_init ~root_state ~workspace ~libname =
88-
Protect.eval ~f:(doc_init ~root_state ~workspace ~libname) ()
88+
Protect.eval ~pure:true ~f:(doc_init ~root_state ~workspace ~libname) ()

coq/interp.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ let coq_interp ~st cmd =
2727
Vernacinterp.interp ~st cmd |> State.of_coq
2828

2929
let interp ~st cmd =
30-
Protect.eval cmd ~f:(fun cmd ->
30+
Protect.eval cmd ~pure:true ~f:(fun cmd ->
3131
let res = coq_interp ~st cmd in
3232
{ Info.res })

coq/parsing.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let parse ~st ps =
99
Vernacstate.Parser.parse st Pvernac.(main_entry mode) ps
1010
|> Option.map Ast.of_coq
1111

12-
let parse ~st ps = Protect.eval ~f:(parse ~st) ps
12+
let parse ~st ps = Protect.eval ~pure:false ~f:(parse ~st) ps
1313

1414
(* Read the input stream until a dot or a "end of proof" token is encountered *)
1515
let parse_to_terminator : unit Pcoq.Entry.t =

coq/print.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ let pr_letype_env ~goal_concl_style env sigma x =
33

44
let pr_letype_env ~goal_concl_style env sigma x =
55
let f = pr_letype_env ~goal_concl_style env sigma in
6-
Protect.eval ~f x
6+
Protect.eval ~pure:true ~f x

coq/protect.ml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,31 @@ module R = struct
3030
end
3131

3232
(* Eval and reify exceptions *)
33-
let eval_exn ~f x =
33+
let rec eval_exn ~f ~retry x =
3434
try
3535
let res = f x in
3636
R.Completed (Ok res)
3737
with
3838
| Sys.Break -> R.Interrupted
3939
| exn ->
40-
let e, info = Exninfo.capture exn in
40+
let exn, info = Exninfo.capture exn in
4141
let loc = Loc.(get_loc info) in
42-
let msg = CErrors.iprint (e, info) in
43-
if CErrors.is_anomaly e then R.Completed (Error (Anomaly (loc, msg)))
44-
else R.Completed (Error (User (loc, msg)))
42+
let msg = CErrors.iprint (exn, info) in
43+
let anomaly = CErrors.is_anomaly exn in
44+
let bt = Printexc.backtrace_status () in
45+
match anomaly, bt, retry with
46+
| true, true, _
47+
| true, false, false ->
48+
R.Completed (Error (Anomaly (loc, msg)))
49+
| true, false, true ->
50+
(* This doesn't work because the state unfreeze will restore the
51+
"no-backtrace" status *)
52+
CDebug.set_flags "backtrace";
53+
let res = eval_exn ~f ~retry:false x in
54+
CDebug.set_flags "-backtrace";
55+
res
56+
| false, _, _ ->
57+
R.Completed (Error (User (loc, msg)))
4558

4659
module E = struct
4760
type 'a t =
@@ -59,8 +72,8 @@ end
5972
let fb_queue : Message.t list ref = ref []
6073

6174
(* Eval with reified exceptions and feedback *)
62-
let eval ~f x =
63-
let r = eval_exn ~f x in
75+
let eval ~f ~pure x =
76+
let r = eval_exn ~retry:pure ~f x in
6477
let feedback = List.rev !fb_queue in
6578
let () = fb_queue := [] in
6679
{ E.r; feedback }

coq/protect.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ val fb_queue : Message.t list ref
4040
(** Eval a function and reify the exceptions. Note [f] _must_ be pure, as in
4141
case of anomaly [f] may be re-executed with debug options. Beware, not
4242
thread-safe! *)
43-
val eval : f:('i -> 'o) -> 'i -> 'o E.t
43+
val eval : f:('i -> 'o) -> pure:bool -> 'i -> 'o E.t

coq/state.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ let in_state ~st ~f a =
9696
Vernacstate.unfreeze_interp_state st;
9797
f a
9898
in
99-
Protect.eval ~f a
99+
Protect.eval ~pure:true ~f a
100100

101101
let admit ~st =
102102
let () = Vernacstate.unfreeze_interp_state st in

0 commit comments

Comments
 (0)