ocsigen / lwt

OCaml promises and concurrent I/O

Home Page:https://ocsigen.org/lwt

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Backtraces appear to be broken.

haesbaert opened this issue · comments

I can't seem to get traces to work correctly, the trace is incomplete does not show the module that generated an exception, first I was generating a normal exception than I was told I needed to Lwt.wrap it, still have the same behaviour, this is the backtrace I get:

Fatal error: exception Failure("boom")
Raised at file "src/core/lwt.ml", line 788, characters 22-23
Called from file "src/unix/lwt_main.ml", line 34, characters 8-18
No line for the Boom.crash() call.
Called from file "exc.ml", line 13, characters 2-26 (This is the Lwt_main.run)

On my original case I don't even get the bottom line, my trace starts at lwt_main.ml line 34.

exc.ml:

open Lwt

let () = Printexc.record_backtrace true

let rec thread () =
  lwt () = Lwt_unix.sleep 1.0 in
  lwt () = wrap (fun () -> Boom.crash ()) in
  thread ()

let _ =
  Lwt_main.run (thread ())

boom.ml:

let crash () = failwith "boom"

here is the _log build:

### Starting build.
# Target: exc.ml.depends, tags: { bin_annot, debug, extension:ml, file:exc.ml, ocaml, ocamldep, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamldep -package lwt.unix -package lwt.syntax -ppopt -lwt-debug -syntax camlp4o -modules exc.ml > exc.ml.depends
# Target: boom.ml.depends, tags: { bin_annot, debug, extension:ml, file:boom.ml, ocaml, ocamldep, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamldep -package lwt.unix -package lwt.syntax -ppopt -lwt-debug -syntax camlp4o -modules boom.ml > boom.ml.depends # cached
# Target: boom.cmo, tags: { bin_annot, byte, compile, debug, extension:cmo, extension:ml, file:boom.cmo, file:boom.ml, implem, ocaml, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamlc -c -g -bin-annot -strict-sequence -package lwt.unix -package lwt.syntax -ppopt -lwt-debug -syntax camlp4o -o boom.cmo boom.ml # cached
# Target: exc.cmo, tags: { bin_annot, byte, compile, debug, extension:cmo, extension:ml, file:exc.cmo, file:exc.ml, implem, ocaml, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamlc -c -g -bin-annot -strict-sequence -package lwt.unix -package lwt.syntax -ppopt -lwt-debug -syntax camlp4o -o exc.cmo exc.ml
# Target: boom.cmx, tags: { bin_annot, compile, debug, extension:cmx, extension:ml, file:boom.cmx, file:boom.ml, implem, native, ocaml, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamlopt -c -g -bin-annot -strict-sequence -package lwt.unix -package lwt.syntax -ppopt -lwt-debug -syntax camlp4o -o boom.cmx boom.ml # cached
# Target: exc.cmx, tags: { bin_annot, compile, debug, extension:cmx, extension:ml, file:exc.cmx, file:exc.ml, implem, native, ocaml, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamlopt -c -g -bin-annot -strict-sequence -package lwt.unix -package lwt.syntax -ppopt -lwt-debug -syntax camlp4o -o exc.cmx exc.ml
# Target: exc.native, tags: { bin_annot, debug, dont_link_with, extension:native, file:exc.native, link, native, ocaml, package(lwt.syntax), package(lwt.unix), ppopt(-lwt-debug), program, quiet, strict_sequence, syntax(camlp4o), traverse }
ocamlfind ocamlopt -linkpkg -g -package lwt.unix -package lwt.syntax -syntax camlp4o boom.cmx exc.cmx -o exc.native
# Compilation successful.

Backtraces extracted from the native stack don't make sense in a concurrency monad (computations are captured and usually reinstantiated in a totally different context; here the scheduler as shown by lines referring to lwt.ml).

I made a proof of concept of backtrace-aware lwt but it is left in a broken state at the moment (you'll need a specific version of owee and it'll work only on amd64 linux).
There is a long term project to improve quality of both OCaml backtraces and EDSLs ones, it's just not ready yet.

Just to clarify, what I'm seeing is expected ?
By reading the manual one would expect it to show as described in:

Backtrace support

When using Lwt, exceptions are not recorded by the ocaml runtime, and so you don't get backtraces. However it is possible to get them when using the syntax extension. All you have to do is to pass the -lwt-debug switch to camlp4:

$ ocamlfind ocamlc -syntax camlp4o -package lwt.syntax \
    -ppopt -lwt-debug -linkpkg -o foo foo.ml

Yup you're correct, I forgot about the syntax extension which I didn't use for a long time.
I'll let official lwt maintainers comment (sorry, I didn't make it clear, my proof-of-concept is not directly related to main lwt development).

Try it with ocaml 4.01. There is an open bug report around this issue: http://caml.inria.fr/mantis/view.php?id=6556
This might also have broken Lwt.backtrace_bind. I didn't verify it, but i assume passing an exception around as parameter will have a similar effect as let e = exn in raise e

This was fixed by @gabelevi in #554 and #556 (many thanks).