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
Mingw64 + threads + system exception raised through longjmp() = crash #7638
Comments
Comment author: @alainfrisch Xavier: did you try other ports (especially msvc64) and/or older versions of OCaml (4.05)? |
Comment author: @xavierleroy
Not yet. A git bisect is in progress. More data points are always welcome. |
Comment author: @alainfrisch My current data points:
Also, replacing the call to |
Comment author: @xavierleroy Thanks a lot Alain for the data points. This is consistent with the hypothesis that Mingw64 has a bug in the way it uses setjmp/longjmp from Microsoft's CRT. (That MSVC has no problems can be explained in several way: use of a different CRT, use of the same CRT but in a different manner, special compilation of setjmp and longjmp, etc.) |
Comment author: @xavierleroy That leaves us with the question of finding a workaround. Ideally, Mingw64 would fix the issue and we wouldn't have anything to do, but I'm afraid this will take time, and in the meantime the Mingw64 port of OCaml is seriously broken. __builtin_setjmp / __builtin_longjmp could be used if we don't mind the fact that these are undocumented GCC features intended to help with the implementation of setjmp / longjmp, if I understood correctly. I thought of using "frame-based structured exception handling" (the C++-style exception mechanism that Microsoft added to C) as a replacement for this particular use of setjmp / longjmp in the bytecode runtime system. It would do the job, but it is not implemented by the Mingw64 compiler, only by the MSVC compiler. |
Comment author: @alainfrisch Also related: http://www.agardner.me/golang/windows/cgo/64-bit/setjmp/longjmp/2016/02/29/go-windows-setjmp-x86.html It seems several people have experienced unexplained problems with setjmp/longjmp under mingw64 and decided to switch to using _builtin* variants, which was successful. So I'd say: without more information or ideas for another workaround, let's follow the crowd. The Windows' mysterious ways. (Oh, and sourceforge.net is in "static offline mode" now...) |
Comment author: @xavierleroy Pull request at #1376 |
Original bug ID: 7638
Reporter: @xavierleroy
Status: resolved (set by @xavierleroy on 2017-09-28T09:44:41Z)
Resolution: fixed
Priority: normal
Severity: major
Platform: Mingw64
OS: Windows 64
OS Version: 10
Version: 4.06.0 +dev/beta1/beta2/rc1
Target version: 4.06.0 +dev/beta1/beta2/rc1
Fixed in version: 4.06.0 +dev/beta1/beta2/rc1
Category: platform support (windows, cross-compilation, etc)
Monitored by: @gasche
Bug description
Consider:
let crashme v =
ignore (Sys.getenv v)
let _ =
let th = Thread.create crashme "no such variable" in
Thread.join th
Compile this program to bytecode using the Mingw64 port of OCaml and the trunk current at the time of this PR, i.e. 4.06.0+dev. On a Windows 10 machine (ocaml-mingw-64-b from Inria's CI pool, to be exact), the program crashes reproducibly.
Running it under a debugger shows a segfault in the call to longjmp() from caml_raise(), corresponding to Sys.getenv raising Not_found.
A similar issue shows up with lib-threads/socketsbuf.ml from the OCaml test suite.
The program works fine when compiled to native code.
This might be an instance of the setjmp/longmp problem reported here: https://sourceforge.net/p/mingw-w64/bugs/406/
Indeed, the problem goes away if, as suggested in the problem report above, the bytecode interpreter is modified to use __builtin_setjmp and __builtin_longjmp instead of setjmp/longjmp. Note however that those GCC builtins are undocumented.
The text was updated successfully, but these errors were encountered: