Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005707OCamlback end (clambda to assembly)public2012-07-31 13:572015-12-11 19:08
Assigned Toxleroy 
Platformx86_64 OSLinuxOS Version3.2.0
Product Version3.12.1 
Target Version4.00.1+devFixed in Version4.00.1+dev 
Summary0005707: Segfault when called from C on 64bit -fPIC (function with more than 8 parameters)
DescriptionDear 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:
---- ------------------
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";

let test i : unit =
  print_endline ("Initialising: " ^ (string_of_int i)); 1 2 3 4 5 6 7 8 9;

(* test 10;;*)

let _ = Callback.register "test" test;;
----- end

----- interface.c
#include <caml/mlvalues.h>
#include <caml/callback.h>

#include "interface.h"

void ocaml_initialize(char** 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 ReproduceYou 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 -ccopt -shared interface.c
g++ -Wall main.cpp -lmytest -o test

or unpack the tar file and call make.
Additional Informationg++ : (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
TagsNo tags attached.
Attached Filestgz file icon ocaml_64_segfault.tgz [^] (1,426 bytes) 2012-07-31 13:57

- Relationships
has duplicate 0005717closeddoligez Fatal error: out of memory. 

-  Notes
lefessan (developer)
2012-07-31 15:08

Use "caml_startup(argv)" instead of "caml_main(argv)".

See [^]
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.
xleroy (administrator)
2012-07-31 16:25

Here is what happens. Since was compiled in shared library mode, the tail call from M1.test to goes through the dynamic loader, which clobbers registers r10 and r11, which ocamlopt uses to pass parameter "p9" and the implicit environment parameter to

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.
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 ?
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.
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
2015-12-11 19:08 xleroy Status resolved => closed
2017-02-23 16:35 doligez Category OCaml backend (code generation) => Back end (clambda to assembly)
2017-02-23 16:44 doligez Category Back end (clambda to assembly) => back end (clambda to assembly)

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker