| Anonymous | Login | Signup for a new account | 2013-05-24 21:37 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | |||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | |||||||
| 0005707 | OCaml | OCaml backend (code generation) | public | 2012-07-31 13:57 | 2012-12-18 14:54 | |||||||
| Reporter | georg | |||||||||||
| Assigned To | xleroy | |||||||||||
| Priority | normal | Severity | crash | Reproducibility | always | |||||||
| Status | resolved | Resolution | fixed | |||||||||
| Platform | x86_64 | OS | Linux | OS Version | 3.2.0 | |||||||
| Product Version | 3.12.1 | |||||||||||
| Target Version | 4.00.1+dev | Fixed in Version | 4.00.1+dev | |||||||||
| Summary | 0005707: Segfault when called from C on 64bit -fPIC (function with more than 8 parameters) | |||||||||||
| Description | Dear developers, I found a severe BUG in ocaml connected with ocaml code as a libary called from C++ under 64bit. I compiled ocaml 3.12.1 version with -fPIC as in the INSTALL. The problem occurs when a function with more than 8 parameters is called. The last parameters do have the right value and if afterwards a reference is accessed than a segmentation fault occurs, see the code below. Some Observations: Calling it natively as an ocaml executable works. Commenting the access to !v removes the segmentation fault but still the values are wrong. Uncommenting line "test 10", causes the error already at this call and the subsequent call from C runs fine! Here the code: also attached as a tar file: ---- m1.ml ------------------ module M2 = struct let v = ref 0;; let foo p1 p2 p3 p4 p5 p6 p7 p8 p9 = prerr_endline "start"; print_endline (string_of_int p1); print_endline (string_of_int p2); print_endline (string_of_int p3); print_endline (string_of_int p4); print_endline (string_of_int p5); print_endline (string_of_int p6); print_endline (string_of_int p7); print_endline (string_of_int p8); print_endline (string_of_int p9); print_endline (string_of_int !v); prerr_endline "end"; ;; end;; let test i : unit = print_endline ("Initialising: " ^ (string_of_int i)); M2.foo 1 2 3 4 5 6 7 8 9; ;; (* test 10;;*) let _ = Callback.register "test" test;; ----- end m1.ml ----- interface.c #include <caml/mlvalues.h> #include <caml/callback.h> #include "interface.h" void ocaml_initialize(char** argv){ caml_main(argv); } void ocaml_test(){ value* test_pointer = caml_named_value("test"); caml_callback(*test_pointer, Val_int(11)); } ------ end interface.c ----- interface.h void ocaml_initialize(char** argv); void ocaml_test(); ----- end interface.h | |||||||||||
| Steps To Reproduce | You need ocaml to be compiled with -fPIC on order to be able to generate a shared libary on 64bit, as written in the INSTALL ./configure -cc "gcc -fPIC" -aspp "gcc -c -fPIC" ocamlopt -o libmytest.so -ccopt -shared interface.c m1.ml g++ -Wall main.cpp -lmytest -o test ./test or unpack the tar file and call make. | |||||||||||
| Additional Information | g++ : (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 ocaml: The Objective Caml toplevel, version 3.12.1 uname: Linux 3.2.0-27-generic 0000043-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux CPU: Intel(R) Core(TM)2 Duo CPU E7600 | |||||||||||
| Tags | No tags attached. | |||||||||||
| Attached Files | ||||||||||||
Notes |
|
|
(0007840) lefessan (developer) 2012-07-31 15:08 |
Use "caml_startup(argv)" instead of "caml_main(argv)". See http://caml.inria.fr/pub/docs/manual-ocaml/manual033.html#toc148 [^] |
|
(0007845) xleroy (administrator) 2012-07-31 15:47 |
> Use "caml_startup(argv)" instead of "caml_main(argv)". In native code, caml_startup and caml_main do exactly the same things, so this doesn't explain the observed crash. Reverting this PR to "new" and trying to reproduce. |
|
(0007846) xleroy (administrator) 2012-07-31 16:25 |
Here is what happens. Since m1.ml was compiled in shared library mode, the tail call from M1.test to M1.M2.foo goes through the dynamic loader, which clobbers registers r10 and r11, which ocamlopt uses to pass parameter "p9" and the implicit environment parameter to M1.M2.foo. We might be able to fix this by using two C-callee-save registers for passing parameters 0000009 and 0000010, e.g. r12 and r13, instead of r10 and r11. That would work around the issue for Linux at least, but no guarantees for other platforms, esp. Win64. |
|
(0007847) lefessan (developer) 2012-07-31 16:41 |
Doesn't that mean that ocamlopt should strictly obey C calling conventions regarding caller-save registers, at least when compiling with -shared ? |
|
(0007848) xleroy (administrator) 2012-07-31 16:46 |
> Doesn't that mean that ocamlopt should strictly obey C calling conventions regarding caller-save registers, at least when compiling with -shared ? No. It means that for parameter passing, ocamlopt should only use registers that the dynamic loader must preserve: either - registers that are used for parameter passing in the C calling convention, or - C callee-save registers (there are no callee-save registers in ocamlopt's conventions) The AMD64 SVR4 ABI specification explicitly allows r11 to be destroyed by the dynamic loader. If my reading of fig 3.4 is correct, all other integer registers should be preserved, including r10 because it can be used to pass a static link to a function. The Linux dynamic loader destroys r10 (hmmmph) and r11, but seems to preserve all other regs. |
|
(0008035) xleroy (administrator) 2012-09-08 18:55 |
Tentative fix in 4.00 bugfix branch (r12907) and on trunk (r12908). The repro case works. The MSVC64 port needs testing. |
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2012-07-31 13:57 | georg | New Issue | |
| 2012-07-31 13:57 | georg | File Added: ocaml_64_segfault.tgz | |
| 2012-07-31 15:08 | lefessan | Note Added: 0007840 | |
| 2012-07-31 15:08 | lefessan | Status | new => resolved |
| 2012-07-31 15:08 | lefessan | Resolution | open => no change required |
| 2012-07-31 15:08 | lefessan | Assigned To | => lefessan |
| 2012-07-31 15:47 | xleroy | Note Added: 0007845 | |
| 2012-07-31 15:47 | xleroy | Status | resolved => new |
| 2012-07-31 15:47 | xleroy | Resolution | no change required => open |
| 2012-07-31 16:25 | xleroy | Note Added: 0007846 | |
| 2012-07-31 16:25 | xleroy | Priority | urgent => normal |
| 2012-07-31 16:25 | xleroy | Status | new => confirmed |
| 2012-07-31 16:28 | lefessan | Assigned To | lefessan => |
| 2012-07-31 16:41 | lefessan | Note Added: 0007847 | |
| 2012-07-31 16:46 | xleroy | Note Added: 0007848 | |
| 2012-09-06 16:41 | doligez | Target Version | => 4.00.1+dev |
| 2012-09-08 18:55 | xleroy | Note Added: 0008035 | |
| 2012-09-08 18:55 | xleroy | Assigned To | => xleroy |
| 2012-09-08 18:55 | xleroy | Status | confirmed => resolved |
| 2012-09-08 18:55 | xleroy | Resolution | open => fixed |
| 2012-09-08 18:55 | xleroy | Fixed in Version | => 4.00.1+dev |
| 2012-12-18 14:54 | frisch | Relationship added | has duplicate 0005717 |
| Copyright © 2000 - 2011 MantisBT Group |