Description of problem: (This is somewhat confusing because I *think* this must have worked on April 16 which is when I built plplot-5.7.3-2.fc7, and the test that fails should have been run then, but the build logs appear to be gone.) I'm afraid I know almost nothing about Ada. This code is adapted from a PlPlot example test case. Perhaps there is an obvious programming error, but it seems like the interface declaration is correct. with Ada.Text_IO, Ada.Numerics, Ada.Numerics.Long_Elementary_Functions, Ada.Strings.Bounded, Interfaces.C, Interfaces.C.Pointers, System, Ada.Strings.Unbounded; use Interfaces.C, Ada.Text_IO, Ada.Strings.Bounded, Ada.Strings.Unbounded, Ada.Numerics, Ada.Numerics.Long_Elementary_Functions; procedure x12b is y0 : array (Integer range 0 .. 9) of Long_Float; procedure Printf( format : in char_array; variable: in Long_Float ); pragma Import(C, Printf, "printf" ); begin y0(0) := 5.0; y0(1) := 15.0; y0(2) := 12.0; y0(3) := 24.0; y0(4) := 28.0; y0(5) := 30.0; y0(6) := 20.0; y0(7) := 8.0; y0(8) := 12.0; y0(9) := 3.0; for i in y0'Range loop printf(To_C("%.0f"), y0(i)); printf(To_C("%.0f"), Long_Float(1980 + i)); end loop; end x12b; When compiled and run on a Fedora Linux x86_64 machine it segfaults (or hangs in an endless loop of segfaults as shown by strace). Runs fine on i686. Originally the code used sprintf: string : char_array(0 .. 20); y0 : array (Integer range 0 .. 9) of Long_Float; procedure Sprintf( buffer : out char_array; format : in char_array; variable: in Long_Float ); pragma Import(C, Sprintf, "sprintf" ); and: sprintf(string, To_C("%.0f"), y0(i)); and that also crashes. This is with gcc-gnat-4.1.1-51.fc5 through gcc-gnat-4.1.2-12. Tested on FC5/6/7.
This is clearly invalid code. procedure Printf( format : in char_array; variable: in Long_Float ); pragma Import(C, Printf, "printf" ); You are lying to the compiler, printf is not printf (const char *, double) but printf (const char *, ...). While on i386 these two happen to have the same calling convention, on x86_64 they don't (vararg functions need to additionally set %rax register to the number of used %xmm* argument). With the incorrect declaration, %rax contains some random value and if it is bigger than 7, the code to save %xmm0..%xmm[%rax-1] registers to stack (see x86_64 ABI) will just jump either to a middle of some instruction or some unrelated instruction. Not sure if Ada allows you to specify a vararg function some way, if yes, use it, if not, you can't call these functions directly, you'd need to write a short wrapper function in C that will do that: int printf_arg_double (const char *fmt, double d) { return printf (fmt, d); } and call that from Ada instead.
Thanks for the explanation Jakub - much appreciated.