Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007271OCamlmiscpublic2016-06-10 11:362017-10-19 16:16
Reporterfuruse 
Assigned To 
PrioritylowSeverityminorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version4.03.0 
Target Version4.06.0 +dev/beta1/beta2/rc1Fixed in Version4.06.0 +dev/beta1/beta2/rc1 
Summary0007271: Undocumented ocamlc and ocamlopt link behaviour difference
DescriptionI wrote a code like the following to enforce a compilation unit M linked. In bytecode, it works fine:

if false then M.f () (* dummy code to make sure M is linked. *)

However, ocamlopt seems to erase the entire expression. As a result the reference to M is lost and M is never linked together. The intention of linking of M is to execute an initialization side effect in M.

This is very confusing behaviour difference between ocamlc and ocamlopt. If it is not a bug, it should be noted in OCaml reference manual 11.5: "Compatibility with the bytecode compiler".
TagsNo tags attached.
Attached Files

- Relationships
related to 0006509resolvedgasche [github patch] add -linkall flag to ocamlcommon archives 

-  Notes
(0015978)
furuse (reporter)
2016-06-10 11:44

You can reproduce the problem with the following code:

(* a.ml *)

let f = ref (fun () -> assert false : unit -> unit)

----------
(* b.ml *)

let () = A.f := (fun () -> prerr_endline ":-)")
let g x y = x + y

----------
(* c.ml *)

let () = if false then ignore (B.g 1 2)
let () = !A.f ()

----------

$ ocamlopt -c a.ml
$ ocamlopt -c b.ml
$ ocamlopt -o ab.cmxa -a a.cmx b.cmx
$ ocamlopt -o test ab.cmxa c.ml
$ ./test
Fatal error: exception Assert_failuire("a.ml", 1, 23)


I found this when I was playing with compiler-libs.common of 4.03.0. Env.scrape_alias failed since Env.strengthen was not initialized by Mtype. I tried to link Mtype by inserting a dummy expression like if false then Mtype.scrape Env.empty (Mty_signature []) , but it did not make ocamlopt link Mtype.

Currently I use the following instead to avoid the issue:

let () = ignore (Mtype.strengthen == Mtype.strengthen)
(0016266)
doligez (administrator)
2016-09-02 17:45

I think the recommended way to force inclusion (under 4.03.0 or later) would be:

  ignore (Sys.opaque_identity Mtype.scrape)

But I agree we need to (at least) document the difference between byte-code and native.
(0016267)
gasche (administrator)
2016-09-02 17:52

The particular case of compiler-libs.common is related to 0006509 , see in particular the discussion in

  https://github.com/ocaml/ocaml/pull/53 [^]

I still think that relying on module linking to initialize back-patched functions in this case is fragile and that we should have a more explicit API for compiler-libs users to explicitly request their initialization -- and thus force their linking.
(0016964)
shinwell (developer)
2016-12-12 16:15

I'm not sure the Sys.opaque_identity line that @doligez writes above will work except when using Flambda---we should check.
(0017270)
xleroy (administrator)
2017-02-16 09:43

My recommendation is to apply -linkall to the libraries or compilation units that have initialization code with important effects. Note that in 4.05 and up -linkall can be applied to a single compilation unit.

I'm not sure what needs to be done / can be done for release 4.05 and even for future releases.
(0018593)
xleroy (administrator)
2017-10-19 16:16

Mentioned this issue in section 11.5 of the manual (differences ocamlc/ocamlopt).

- Issue History
Date Modified Username Field Change
2016-06-10 11:36 furuse New Issue
2016-06-10 11:44 furuse Note Added: 0015978
2016-09-02 17:45 doligez Note Added: 0016266
2016-09-02 17:46 doligez Target Version => 4.04.0 +dev / +beta1 / +beta2
2016-09-02 17:46 doligez Status new => acknowledged
2016-09-02 17:50 gasche Relationship added related to 0006509
2016-09-02 17:52 gasche Note Added: 0016267
2016-09-08 11:18 shinwell Target Version 4.04.0 +dev / +beta1 / +beta2 => 4.05.0 +dev/beta1/beta2/beta3/rc1
2016-12-12 16:15 shinwell Note Added: 0016964
2017-02-16 09:43 xleroy Note Added: 0017270
2017-02-17 15:24 frisch Severity major => minor
2017-02-17 15:24 frisch Summary Undocumented ocamlc and ocamlopt behaviour difference => Undocumented ocamlc and ocamlopt link behaviour difference
2017-02-22 15:27 xleroy Priority high => low
2017-02-22 15:27 xleroy Target Version 4.05.0 +dev/beta1/beta2/beta3/rc1 => 4.06.0 +dev/beta1/beta2/rc1
2017-02-23 16:36 doligez Category OCaml general => -OCaml general
2017-02-23 17:11 doligez Category -OCaml general => misc
2017-10-19 16:16 xleroy Note Added: 0018593
2017-10-19 16:16 xleroy Status acknowledged => resolved
2017-10-19 16:16 xleroy Resolution open => fixed
2017-10-19 16:16 xleroy Fixed in Version => 4.06.0 +dev/beta1/beta2/rc1


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker