Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect module initialisation order with "external" declarations #4166

Closed
vicuna opened this issue Nov 21, 2006 · 5 comments
Closed

Incorrect module initialisation order with "external" declarations #4166

vicuna opened this issue Nov 21, 2006 · 5 comments
Labels
bug
Milestone

Comments

@vicuna
Copy link

@vicuna vicuna commented Nov 21, 2006

Original bug ID: 4166
Reporter: @mmottl
Status: resolved (set by @xavierleroy on 2015-11-22T10:45:03Z)
Resolution: open
Priority: normal
Severity: minor
Version: 3.09.3
Target version: 4.03.0+dev / +beta1
Fixed in version: 4.03.0+dev / +beta1
Category: ~DO NOT USE (was: OCaml general)
Has duplicate: #6956
Related to: #4374 #6063
Monitored by: yziquel mehdi @ygrek @hcarty @dbuenzli @Chris00 @mmottl

Bug description

We have a module (lets call it "Foo") that interfaces C-bindings and exports functions defined as "external" in its .mli-file. This module is packed with others into one module, which again is part of a .cmxa-file.

If we link this library with another module (say, "Bar") that uses only functions defined "external" in "Foo", we observed that toplevel expressions in "Foo" did not get evaluated.

Here is a schematic example:

foo.ml:

external foo : unit -> unit = "foo"
external init : unit -> unit = "init"

let () =
print_endline "init";
init ()

foo.mli:

external foo : unit -> unit

bar.ml:

let () =
print_endline "bar";
Foo.foo ()

Since "Bar" depends on "Foo", you would expect that the toplevel expression in "foo.ml" gets evaluated first, which should print "init" and e.g. initialise the C-bindings. But we see "bar" first, and our application crashes, because the C-bindings are not evaluated.

Interestingly, changing "foo.mli" as follows solves the problem:

foo.mli:

val foo : unit -> unit

This indicates that exclusively calling functions exported as "external" will prevent the linker from figuring out which modules should be initialized first. This seems to be a bug, it shouldn't matter whether we use "val" or "external".

@vicuna
Copy link
Author

@vicuna vicuna commented Nov 24, 2006

Comment author: @damiendoligez

I'm downgrading this to "minor" since there is an easy workaround: always use "val" instead of "external" in your .mli files.

@vicuna
Copy link
Author

@vicuna vicuna commented Oct 26, 2010

Comment author: @ygrek

and it also bites those lazy folks (like me) who do not write mli interfaces..

@vicuna
Copy link
Author

@vicuna vicuna commented Dec 23, 2010

Comment author: @edwintorok

Perhaps ocaml should give a warning if you use 'external' in .mli files.

Due to this bug exceptions are not registered in C code, which causes caml_raise_arg_with to be invoked with a NULL exception, which in turn causes a segfault.

@vicuna
Copy link
Author

@vicuna vicuna commented Dec 31, 2013

Comment author: @garrigue

Since a similar problem appears when introducing module aliases, we might want to solve the two simultaneously. A clean approach would require adding dependency information to the cmo format.

@vicuna
Copy link
Author

@vicuna vicuna commented Nov 22, 2015

Comment author: @xavierleroy

See #289. Fixed by commit 07b8eb3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.