Using ocamldebug with dune

I have a problem trying to use ocamldebug on programs compiled with dune.
Suppose I have the following dune project:

<root>/src/lib/foo.ml
              /dune
<root>/example/main.ml
              /dune 

where foo.ml defines a library and main.mluses it. For ex (silly example)

(* foo.ml *)
let bar x =
  let y =  x*2  in
  y+1

(* main.ml *)
let _ =
  let r1 = Foo.bar 1 in
  let r2 = Foo.bar 2 in
  print_int (r1+r2)

These files are, classicaly, compiled with the following dune stanzas, resp.:

(library
  (name foo)
  (modules foo ))

and

(executable
 (name main)
 (modes byte)
 (modules main)
 (libraries foo))

To use ocamldebug the resulting program (main.bc), i cd to the corresponding _build subdir:

cd _build/default/example

and run ocamldebug (either from the CL or Emacs) passing main.bc as the program name and no argument (IIUC dune uses the -g ocamlc argument for bytecode pgms).

I would have imagined that setting a breakpoint, say at line 2 of foo.ml would not work because the current directory (_build/default/example) does not contain the corresponding source file. Surprizingly enough, it does:

(ocd) break @ Foo 2
Loading program... done.
Breakpoint 1 at 0:10492: file src/lib/foo.ml, line 2, characters 3-25

It seems that dune has, somehow “under the hood” adjusted the directory variable of ocamldebug. This is confimed by inspecting this variable:

(ocd) directory
Reinitialize directory list ? (y or n) n
Directories:  . /Users/jserot/.opam/4.10.0/lib/ocaml
  /Users/jserot/.opam/4.10.0/.opam-switch/build/ocaml-base-compiler.4.10.0/stdlib
  /Users/jserot/.opam/4.10.0/lib/ocaml
  /Users/jserot/Dev/ml/dune-debug/_build/default
  /Users/jserot/Dev/ml/dune-debug/_build/default/example
  /Users/jserot/Dev/ml/dune-debug/_build/default/example/.main.eobjs/byte
  /Users/jserot/Dev/ml/dune-debug/_build/default/src/lib
  /Users/jserot/Dev/ml/dune-debug/_build/default/src/lib/.foo.objs/byte

So far so good.
The problem is that setting a breakpoint in main.ml does not work:

(ocd) list "main.ml"
1 let _ =
2   let r1 = Foo.bar 1 in
3   let r2 = Foo.bar 2 in
4   print_int (r1+r2)
Position out of range.
(ocd) break @ Main 2
Can't find any event there.

What’s going on here ? The corresponding source file

  • is in directory listed in the ocamldebug directory variable
  • has been compiled with -g

Am i missing sth ?

Hi,

I think you are in the same situation as this dune issue: Byte target can't be debugged with ocamldebug · Issue #4347 · ocaml/dune · GitHub

The solution seems to refer to the main module as @dune__exe__Main and it should be better in dune 3.0.

My quick search for similar issues was apparently too quick :wink:

Setting the breakpoint with

 break @ dune__exe__Main 2

works.

What is specially misleading is that this explicit “demangling” is not required for other modules (such as Foo here)…

Another inconvenient is that breakpoints cannot be set from Emacs this way :frowning:

Thanks for the pointer anyway