* [Caml-list] Segmentationfault on 64bit when called from C
@ 2012-07-31 12:17 Georg Martius
2012-07-31 12:59 ` Gerd Stolpmann
2012-07-31 13:11 ` Anil Madhavapeddy
0 siblings, 2 replies; 5+ messages in thread
From: Georg Martius @ 2012-07-31 12:17 UTC (permalink / raw)
To: caml-list
Dear all,
I experienced a very intricate bug in the 64bit runtime that took me some days
to nail down. I submitted a bug report #5707.
Here is what I found: When ocaml code is compiled as as a libary and called
from C++ under 64bit I get a broken stack for functions with more than 8
parameters. I compiled ocaml 3.12.1 version with -fPIC. BTW: everthing works
fine on 32bit.
The problem occurs when a function with more than 8 parameters is called. The
last parameters do have the right value. If afterwards a reference is accessed
then a segmentation fault occurs, see the code below.
Here the code: (in the bug report I also attached 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
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
---- output:
Initialising: 11
start
1
2
3
4
5
6
7
8
70367718054944
Segmentation fault (core dumped)
--- end outpuyt
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!
Best regards,
Georg
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Segmentationfault on 64bit when called from C
2012-07-31 12:17 [Caml-list] Segmentationfault on 64bit when called from C Georg Martius
@ 2012-07-31 12:59 ` Gerd Stolpmann
2012-07-31 14:03 ` Georg Martius
2012-07-31 13:11 ` Anil Madhavapeddy
1 sibling, 1 reply; 5+ messages in thread
From: Gerd Stolpmann @ 2012-07-31 12:59 UTC (permalink / raw)
To: Georg Martius; +Cc: caml-list
Just a rough guess: The frametable is not initialized. Quite funny that
it crashes so quickly. (Maybe more is not initialized, maybe the heap
register, so it crashes at the first allocation.)
You cannot just link Ocaml code without adding the frametable. This is a
description of how the stack and the CPU registers are used at runtime.
If it is missing the OCaml runtime thinks that the Ocaml code is C code,
and applies the wrong conventions.
The -shared switch generates a library that is prepared to be loaded
with Dynlink. Dynlink registers the frametable.
You should consider using -output-obj to create a library that can be
loaded without such tricks (see section 18.7.5 of the Ocaml manual).
Gerd
Am Dienstag, den 31.07.2012, 14:17 +0200 schrieb Georg Martius:
> Dear all,
>
> I experienced a very intricate bug in the 64bit runtime that took me some days
> to nail down. I submitted a bug report #5707.
> Here is what I found: When ocaml code is compiled as as a libary and called
> from C++ under 64bit I get a broken stack for functions with more than 8
> parameters. I compiled ocaml 3.12.1 version with -fPIC. BTW: everthing works
> fine on 32bit.
>
> The problem occurs when a function with more than 8 parameters is called. The
> last parameters do have the right value. If afterwards a reference is accessed
> then a segmentation fault occurs, see the code below.
>
> Here the code: (in the bug report I also attached 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
>
> 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
> ---- output:
> Initialising: 11
> start
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 70367718054944
> Segmentation fault (core dumped)
> --- end outpuyt
>
> 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!
>
> Best regards,
> Georg
>
>
--
------------------------------------------------------------
Gerd Stolpmann, Darmstadt, Germany gerd@gerd-stolpmann.de
Creator of GODI and camlcity.org.
Contact details: http://www.camlcity.org/contact.html
Company homepage: http://www.gerd-stolpmann.de
*** Searching for new projects! Need consulting for system
*** programming in Ocaml? Gerd Stolpmann can help you.
------------------------------------------------------------
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Segmentationfault on 64bit when called from C
2012-07-31 12:17 [Caml-list] Segmentationfault on 64bit when called from C Georg Martius
2012-07-31 12:59 ` Gerd Stolpmann
@ 2012-07-31 13:11 ` Anil Madhavapeddy
1 sibling, 0 replies; 5+ messages in thread
From: Anil Madhavapeddy @ 2012-07-31 13:11 UTC (permalink / raw)
To: Georg Martius; +Cc: caml-list
Interesting; I'm seeing a similar issue that could be to do with the frametable
not being initialised soon enough on OSX Mountain Lion. It only manifests when
recording backtraces in native mode, but I haven't quite had the time to chase
it down fully yet. However, the below bug report does show where you can init
the frametable earlier to work around the bug.
http://caml.inria.fr/mantis/view.php?id=5700
-anil
On 31 Jul 2012, at 13:17, Georg Martius <georg.martius@web.de> wrote:
> Dear all,
>
> I experienced a very intricate bug in the 64bit runtime that took me some days
> to nail down. I submitted a bug report #5707.
> Here is what I found: When ocaml code is compiled as as a libary and called
> from C++ under 64bit I get a broken stack for functions with more than 8
> parameters. I compiled ocaml 3.12.1 version with -fPIC. BTW: everthing works
> fine on 32bit.
>
> The problem occurs when a function with more than 8 parameters is called. The
> last parameters do have the right value. If afterwards a reference is accessed
> then a segmentation fault occurs, see the code below.
>
> Here the code: (in the bug report I also attached 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
>
> 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
> ---- output:
> Initialising: 11
> start
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 70367718054944
> Segmentation fault (core dumped)
> --- end outpuyt
>
> 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!
>
> Best regards,
> Georg
>
>
> --
> Caml-list mailing list. Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Segmentationfault on 64bit when called from C
2012-07-31 12:59 ` Gerd Stolpmann
@ 2012-07-31 14:03 ` Georg Martius
2012-07-31 14:29 ` Xavier Leroy
0 siblings, 1 reply; 5+ messages in thread
From: Georg Martius @ 2012-07-31 14:03 UTC (permalink / raw)
To: caml-list; +Cc: Gerd Stolpmann
On Tuesday 31 July 2012 14:59:14 Gerd Stolpmann wrote:
> Just a rough guess: The frametable is not initialized. Quite funny that
> it crashes so quickly. (Maybe more is not initialized, maybe the heap
> register, so it crashes at the first allocation.)
>
> You cannot just link Ocaml code without adding the frametable. This is a
> description of how the stack and the CPU registers are used at runtime.
> If it is missing the OCaml runtime thinks that the Ocaml code is C code,
> and applies the wrong conventions.
>
> The -shared switch generates a library that is prepared to be loaded
> with Dynlink. Dynlink registers the frametable.
>
> You should consider using -output-obj to create a library that can be
> loaded without such tricks (see section 18.7.5 of the Ocaml manual).
ocamlopt -output-obj -o camlcode.o interface.c m1.ml
gcc -fPIC -g -Wall -c -I/usr/local/lib/ocaml interface.c
gcc -fPIC -o test main.c camlcode.o interface.o -L/usr/local/lib/ocaml -lunix
-lm -lasmrun -ldl
works, but
ocamlopt -o libmytest.so -output-obj interface.c m1.ml
gcc -Wall main.c -lmytest -o test
does not! Is it clear why it doesn't work?
So I get away with static linking for now.
Thanks!
Georg
--
---- Georg Martius, Tel: +49 177 6413311 -----
------- http://www.flexman.homeip.net ----------
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Segmentationfault on 64bit when called from C
2012-07-31 14:03 ` Georg Martius
@ 2012-07-31 14:29 ` Xavier Leroy
0 siblings, 0 replies; 5+ messages in thread
From: Xavier Leroy @ 2012-07-31 14:29 UTC (permalink / raw)
To: caml-list
On Tuesday 31 July 2012 14:59:14 Gerd Stolpmann wrote:
> The -shared switch generates a library that is prepared to be loaded
> with Dynlink. Dynlink registers the frametable.
You're right that .so libraries produced by -shared should only be
used in conjunction with Dynlink. However, in this case the frame
table isn't the culprit, as the crash occurs before the GC even has a
chance to run.
On 07/31/2012 04:03 PM, Georg Martius wrote:
> ocamlopt -output-obj -o camlcode.o interface.c m1.ml
> gcc -fPIC -g -Wall -c -I/usr/local/lib/ocaml interface.c
> gcc -fPIC -o test main.c camlcode.o interface.o -L/usr/local/lib/ocaml -lunix
> -lm -lasmrun -ldl
>
> works, but
> ocamlopt -o libmytest.so -output-obj interface.c m1.ml
> gcc -Wall main.c -lmytest -o test
> does not! Is it clear why it doesn't work?
See my comments on PR#5707. In the latter case, the dynamic loader is
invoked and trashes registers r10 and r11, which ocamlopt uses to pass
arguments to your "foo" function. We'll have to come up with a better
choice of parameter registers.
> So I get away with static linking for now.
Please do if at all possible. ocamlopt was designed for static
linking, and the relatively recent addition of dynamic linking support
isn't completely mature yet.
- Xavier Leroy
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-07-31 14:29 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-31 12:17 [Caml-list] Segmentationfault on 64bit when called from C Georg Martius
2012-07-31 12:59 ` Gerd Stolpmann
2012-07-31 14:03 ` Georg Martius
2012-07-31 14:29 ` Xavier Leroy
2012-07-31 13:11 ` Anil Madhavapeddy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox