OCaml and backtraces

#1

Why OCaml 4.07.1 gives almost identical backtrace in case of exception?

ERROR: Writing file from Bigarray failed!
ERROR: (Unix.Unix_error "Permission denied" map_file "") Raised at file "format.ml" (inlined), line 242, characters 35-52
Called from file "format.ml", line 469, characters 8-33
Called from file "format.ml", line 484, characters 6-24

It happens in this function and see the code I use to show the backtrace:

let file_write_bigarray ~path ?(pos=0L) ~data =
    let data_size = Bigarray.Array1.dim data in
    try
        let fd = Unix.openfile path ~mode:[Unix.O_WRONLY;Unix.O_CREAT] in
        let ba = Bigarray.array1_of_genarray (Caml.Unix.map_file fd
            ~pos Bigarray.char
            Bigarray.c_layout true [|data_size|])
        in
        Bigarray.Array1.blit data ba;
        Unix.close fd
    with
    | e ->
        Lwt_io.printf "ERROR: Writing file from Bigarray failed!\n" |> ignore;
        let msg = Exn.to_string e
        and stack = Printexc.get_backtrace () in
        Lwt_io.printf "ERROR: %s %s\n" msg stack |> ignore

Ok, the exception string is OK, but why backtrace shows format.ml instead of the actual file name?

0 Likes

#2

Oh, nevermind, found:

1 Like

#3

I added (flags (-g)) (link_flags (... -g)) in my dune file and ran the binary with OCAMLRUNPARAM=b set, but backtrace is still the same.

0 Likes

#4

The problem is that Format catches and reraises the exception polluting the backtrace along the way. This is behavior should be fixed in 4.08.0 where Format uses raise_notrace to avoid this very issue.

5 Likes

#5

As an aside, dune already defaults to compiling with -g (source). Also, OCAMLRUNPARAM is only evaluated by the bytecode versions, not the native binary.

0 Likes

#6

Yes, I figured later that dune builds with symbols by default. Good to know the environment variable doesn’t work in the native mode.

0 Likes