Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backtraces from exception raised inside Miou.call_cc do not give the origin of exception #19

Open
kit-ty-kate opened this issue Apr 27, 2024 · 1 comment

Comments

@kit-ty-kate
Copy link
Contributor

$ CAMLRUNPARAM=b dune exec -- ./test.exe
Fatal error: exception Failure("test")
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Re-raised at Miou.await_exn in file "lib/miou.ml", line 1027, characters 23-59
Re-raised at Miou.run in file "lib/miou.ml", line 1376, characters 23-59
Called from Miou_unix.run in file "lib/miou_unix.ml" (inlined), line 351, characters 25-56
Called from Dune__exe__Test in file "test.ml", lines 5-7, characters 2-19
$ cat test.ml
let raise_something () =
  failwith "test"

let () =
  Miou_unix.run @@ fun () ->
  let pr = Miou.call_cc (fun () -> raise_something ()) in
  Miou.await_exn pr
$ cat dune
(executable (name test) (libraries miou.unix))
$ cat dune-project
(lang dune 2.0)
@dinosaure
Copy link
Contributor

You example is unfortunately a bit hard because raise_something is inlined. A solution for your specific case is explained here. So I write this code to show up the Miou's behavior:

$ cat >main.ml <<EOF
external reraise : exn -> 'a = "%reraise"

let[@inline never] id x = x
let[@inline never] raise_something () = failwith "test"
let[@inline never] raise_something () = id (raise_something ())

let () =
  let open Effect.Shallow in
  let retc = Fun.id in
  let exnc = reraise in
  let effc : type c. c Effect.t -> ((c, 'r) continuation -> 'r) option = fun _ -> None in
  let fiber = fiber raise_something in
  Format.printf "effect\n%!";
  match continue_with fiber () { retc; exnc; effc; } with
  | () -> ()
  | exception exn ->
    let bt = Printexc.get_raw_backtrace () in
    Printexc.print_raw_backtrace stdout bt

let () =
  Format.printf "pure\n%!";
  match raise_something () with
  | () -> ()
  | exception exn ->
    let bt = Printexc.get_raw_backtrace () in
    Printexc.print_raw_backtrace stdout bt

let () =
  Format.printf "miou\n%!";
  try Miou.run @@ fun () ->
      let prm = Miou.call_cc raise_something in
      Miou.await_exn prm
  with exn ->
    let bt = Printexc.get_raw_backtrace () in
    Printexc.print_raw_backtrace stdout bt
EOF
$ ocamlfind opt -g -linkpkg -package miou,miou.unix main.ml
$ OCAMLRUNPARAM=b ./a.out                                  
effect
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from Main.raise_something in file "main.ml", line 5, characters 43-63
Re-raised at Main in file "main.ml", line 10, characters 13-20
Called from Main in file "main.ml", line 14, characters 8-52
pure
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from Main.raise_something in file "main.ml", line 5, characters 43-63
Called from Main in file "main.ml", line 22, characters 8-26
miou
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from Main.raise_something in file "main.ml", line 5, characters 43-63
Re-raised at Miou.await_exn in file "lib/miou.ml", line 1027, characters 23-59
Re-raised at Miou.run in file "lib/miou.ml", line 1376, characters 23-59
Called from Main in file "main.ml", line 30, characters 6-100

So Miou (the current main version) does some reraise but keep the source along the backtrace (we can see "main.ml", line 5). I think, if you really want to take into account raise_something, the issue is more related to ocaml than miou.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants