Skip to content

Dynlink support for ocamldebug #6792

@vicuna

Description

@vicuna

Original bug ID: 6792
Reporter: @whitequark
Assigned to: @whitequark
Status: confirmed (set by @damiendoligez on 2015-03-18T14:02:35Z)
Resolution: open
Priority: high
Severity: feature
Target version: undecided
Category: tools (ocaml{lex,yacc,dep,debug,...})
Tags: patch
Has duplicate: #6317
Monitored by: @SkySkimmer @whitequark @gasche

Bug description

Gabriel Scherer has asked me to implement Dynlink support for ocamldebug. I'm attaching the patch. The following is an excerpt from our email exchange describing the capabilities of the patch:

----8<----8<----8<----8<----

$ cat >host.ml
let () = print_endline "hello host"; Dynlink.loadfile "plugin.cma"
$ cat >plugin.ml
let () = print_endline "hello plugin"
$ ocamlc -g -a -o plugin.cma plugin.ml
$ ocamlc -g -o host dynlink.cma host.ml
$ ocamldebug ./host
OCaml Debugger version 4.03.0+dev7-2015-02-08

(ocd) s 22462
Loading program... done.
hello host
hello plugin
Time: 22463 - pc: 1:24 - module Plugin
1 let () = print_endline "hello plugin"<|a|>
(ocd) s 3
Time: 22466 - pc: 0:413204 - module Host
1 let () = print_endline "hello host"; Dynlink.loadfile "plugin.cma"<|a|>
(ocd)

The attached patch (against trunk) implements this feature.
Do note that I broke something that was called "machine interface" in
ocamldebug source; every pc (really position inside a code fragment)
is now prefixed with a number and a colon, e.g. 1:24 above.
The first number signifies the index of the code fragment.

Note that the patch includes a few unrelated bugfixes. Specifically:

  • the changes in meta.c probably should be applied to trunk ASAP.
  • the Debugcom.do_go changes also affect correctness of ocamldebug
    even in trunk.

Note that you cannot set a breakpoint before a module is loaded.
However, a new variable "set break_on_load" (on by default) traps
after dynlink, allowing to set a breakpoint. I.e.:

(ocd) r
Loading program... done.
hello host
Time: 22459 - pc: 0:0
Module(s) Plugin loaded.
(ocd) br @ Plugin 1
Breakpoint 1 at 1:24: file plugin.ml, line 1, characters 10-38
(ocd) r
hello plugin
Time: 22464 - pc: 1:24 - module Plugin
Breakpoint: 1
1 let () = print_endline "hello plugin"<|a|>

Annoyingly, ocamlc doesn't place a debug event at the /start/
of the module initialization code, so you can't break before
the first user code executes.

Interestingly, the patch is completely independent of Dynlink.
It will work for any kind of dynamic code loading, provided that
the debug information is also loaded beforehand. Thus it should
in principle work with toplevel, although the thought of the access
mismanagement inherent to frequently forking a process that is built
around mutating terminal state has kept me from actually trying
to run it.

----8<----8<----8<----8<----

As mentioned, this patch fixes some unrelated minor bugs:

  • in ocamldebug, if you passed a value over max_small_int to "step", then some breakpoints or exceptions could be ignored
  • in meta.c, code fragments coming from Dynlink were registered in caml_code_fragments_table twice, and with different digests, which did not broke closure marshalling because of traversing order, but is still unpleasant.

File attachments

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions