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

Crash toplevel by using compiler-libs #6108

Closed
vicuna opened this issue Jul 30, 2013 · 13 comments
Closed

Crash toplevel by using compiler-libs #6108

vicuna opened this issue Jul 30, 2013 · 13 comments

Comments

@vicuna
Copy link

vicuna commented Jul 30, 2013

Original bug ID: 6108
Reporter: mcclurmc
Status: closed (set by @xavierleroy on 2017-02-16T14:18:32Z)
Resolution: fixed
Priority: normal
Severity: minor
Platform: x86_64
OS: Linux
OS Version: Ubuntu 12.10
Version: 4.00.1
Target version: 4.03.0+dev / +beta1
Fixed in version: 4.03.0+dev / +beta1
Category: ~DO NOT USE (was: OCaml general)
Duplicate of: #6802

Bug description

I load compiler-libs into toplevel using topfind:

# #require "compiler-libs.toplevel";;
/home/mike/.opam/4.00.1/lib/ocaml/threads: added to search path
/home/mike/.opam/4.00.1/lib/ocaml/compiler-libs: added to search path
/home/mike/.opam/4.00.1/lib/ocaml/compiler-libs/ocamlcommon.cma: loaded
/home/mike/.opam/4.00.1/lib/ocaml/compiler-libs/ocamlbytecomp.cma: loaded
/home/mike/.opam/4.00.1/lib/ocaml/compiler-libs/ocamltoplevel.cma: loaded

I can then parse a string:

# Parse.implementation (Lexing.from_string "1 :: []") ;;

However, if I try to make a function out of this...

# let parse_string s = s |> Lexing.from_string |> Parse.implementation ;;
>> Fatal error: parse_string unbound at toplevel
Fatal error: exception Misc.Fatal_error

Steps to reproduce

See description

Additional information

I can repro this using utop, and ocaml toplevel, with and without topfind.

@vicuna
Copy link
Author

vicuna commented Jul 30, 2013

Comment author: @gasche

You don't need compiler-libs.toplevel to get a working lexer and parser from the OCaml compiler. You can use compiler-libs.common, which doesn't link the weird stuff from *.toplevel that provokes the failure here.

(I don't really know what happens, but I suppose the toplevel implementation is not re-entrant, and linking some modules from compiler-libs.toplevel affects the global state of the current toplevel. This is not documented nor supported, and I don't really know why you would want to do that.)

@vicuna
Copy link
Author

vicuna commented Aug 2, 2013

Comment author: @damiendoligez

The toplevel implementation is definitely not re-entrant.

@vicuna
Copy link
Author

vicuna commented Aug 2, 2013

Comment author: meyer

This definitely needs to be in manual, I might prepare a patch for it myself.

I think it's not well known yet how to use compilelibs, usually it's easier to document tools, howver the great premise of compilerlibs, is that they will make such tasks easier. If it comes additionaly with examples, (for -ppx rewriter for instance) then it's great.

@vicuna
Copy link
Author

vicuna commented Feb 24, 2015

Comment author: erwan

Can this bug impact the behavior of ocamlmktop? I have a segv too, and I'd like to know if it can be due to the same origin.

@vicuna
Copy link
Author

vicuna commented Feb 24, 2015

Comment author: @damiendoligez

Do you mean ocamlmktop itself is segfaulting, or the generated toplevel? I don't think the problem described here can happen to a statically-linked program.

@vicuna
Copy link
Author

vicuna commented Feb 25, 2015

Comment author: erwan

In the generated toplevel.

Unfortunately, it's difficult to provide a small example that exhibits the problem as my program is quite big, and the segv occurs seldomly. I should try to load my libs from a standard toplevel to see if segv still occurs.

@vicuna
Copy link
Author

vicuna commented Mar 2, 2015

Comment author: erwan

Ok, i've tried as I said to load my libs from a basic toplevel, and now I got an assert failure in bytecomp/dll.ml line 110.

@vicuna
Copy link
Author

vicuna commented Mar 2, 2015

Comment author: erwan

I was able to reproduce that dll assert pb as follows (it is so
simple that I hope I haven't missed something evident):

let empty.ml be an empty file.

$ ocamlc -a -o empty.cma nums.cma empty.ml

$ ocaml

#use "topfind";;
#require "dynlink";;
#require "unix";; (* works without this #require *)

let _ =
Dynlink.allow_unsafe_modules true; (* nums requires this *)
Dynlink.loadfile "empty.cma"


ps : I am using ocaml 4.02.1+PIC on a amd64 running debian
i may should report that in a separate issue ?

@vicuna
Copy link
Author

vicuna commented Mar 2, 2015

Comment author: erwan

Even simpler (sorry for the bombing):

#use "topfind";;
#require "dynlink";;
#require "unix";; (* works without this #require )
Dynlink.allow_unsafe_modules true;; (
nums requires this *)
Dynlink.loadfile "./.opam/4.02.1+PIC/lib/ocaml/nums.cma";;

tried also on 4.00.0, and 3.12.0 + on 32 arch

@vicuna
Copy link
Author

vicuna commented Mar 3, 2015

Comment author: erwan

I've reported that as a separate issue there :
#6802

@vicuna
Copy link
Author

vicuna commented Dec 5, 2015

Comment author: @xavierleroy

Well, the toplevel loop and the Dynlink library (or: two copies of the toplevel, which is what you get after loading compiler-libs.toplevel) both manipulate the (shared) table of globals of the bytecode interpreter, but in an unsynchronized manner. Hence, they overwrite each other's additions to the table of globals, leading to the crashes observed.

Is there a really compelling use case for Dynlink under the toplevel? If not, I'm tempted to just check !Sys.interactive = false within Dynlink, and fail with an explanation otherwise. If the check is put into Symtable rather than Dynlink, it would also trigger if compiler-libs.toplevel is loaded inside the toplevel.

@vicuna
Copy link
Author

vicuna commented Dec 5, 2015

Comment author: erwan

I'm not the initial reporter of this one, but since I've been bitten too I may answer: indeed I've realized recently I don't really need Dynlink.

The check+the explanation you propose seems like the rigth thing to do.
Thanks.

@vicuna
Copy link
Author

vicuna commented Dec 6, 2015

Comment author: @xavierleroy

Commit [trunk 8e6606d] causes ocamltoplevel.cma to fail cleanly if loaded from the toplevel loop.

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

No branches or pull requests

1 participant