Ticket #1424 (closed bug: fixed)
Argument corruption in FFI with many arguments (maybe 64-bit related)
Description
With many arguments, something strange occurs in argument passing with FFI. The misbehaviour only occurs on my 64-bit machine; the program works correctly on my 32-bit one. It seems as though an extra value is inserted into the argument list.
First, here is the code. There's a foreign function that takes 10 doubles.
chris@mars:~/dev/haskell/ffi$ cat c.c
fC (double a,
double b,
double c,
double d,
double e,
double f,
double g,
double h,
double i,
double j)
{
printf("%f %f %f %f %f %f %f %f %f %f\n", a,b,c,d,e,f,g,h,i,j);
}
chris@mars:~/dev/haskell/ffi$ cat Ffi.hs
{-# OPTIONS_GHC -fglasgow-exts #-}
f :: Double -> Double -> Double -> Double -> Double -> Double -> Double -> Double -> Double -> Double -> IO ()
f a b c d e f g h i j = do
print [a, b, c, d, e, f, g, h, i, j]
fC a b c d e f g h i j
foreign import ccall unsafe "fC" fC ::
Double -> Double -> Double
-> Double -> Double -> Double
-> Double -> Double -> Double -> Double -> IO ()
main = do
f 1 2 3 4 5 6 7 8 9 10
Here is the correct behaviour, on my 32-bit machine. The important output is the line starting with "1.000000 2.000000 3.00[...]"
chris@loki:~/tmp/ffi$ gcc -c c.c c.c: In function ‘fC’: c.c:12: warning: incompatible implicit declaration of built-in function ‘printf’ chris@loki:~/tmp/ffi$ ghc --make Ffi c.o [1 of 1] Compiling Main ( Ffi.hs, Ffi.o ) Linking Ffi ... ./chris@loki:~/tmp/ffi$ ./Ffi [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000 10.000000 chris@loki:~/tmp/ffi$ ghc -v Glasgow Haskell Compiler, Version 6.6.1, for Haskell 98, compiled by GHC version 6.6.1 Using package config file: /usr/lib/ghc-6.6.1/package.conf Using package config file: /home/chris/.ghc/i386-linux-6.6.1/package.conf wired-in package base mapped to base-2.1.1 wired-in package rts mapped to rts-1.0 wired-in package haskell98 mapped to haskell98-1.0 wired-in package template-haskell mapped to template-haskell-2.1 Hsc static flags: -static *** Deleting temp files: Deleting: *** Deleting temp dirs: Deleting: ghc-6.6.1: no input files Usage: For basic information, try the `--help' option. chris@loki:~/tmp/ffi$ gcc -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu Thread model: posix gcc version 4.1.3 20070601 (prerelease) (Debian 4.1.2-12)
Here is the bad behaviour, on my 64-bit machine. Note that the Haskell list has the values [1..10], but the C arguments are 1,2,3,4,5,6,7,8,0,9 (a zero is inserted between 8 and 9).
chris@mars:~/dev/haskell/ffi$ gcc -c c.c c.c: In function ‘fC’: c.c:12: warning: incompatible implicit declaration of built-in function ‘printf’ chris@mars:~/dev/haskell/ffi$ ghc --make Ffi c.o [1 of 1] Compiling Main ( Ffi.hs, Ffi.o ) Linking Ffi ... chris@mars:~/dev/haskell/ffi$ ./Ffi [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 0.000000 9.000000 chris@mars:~/dev/haskell/ffi$ ghc -v Glasgow Haskell Compiler, Version 6.6.1, for Haskell 98, compiled by GHC version 6.6.1 Using package config file: /usr/lib/ghc-6.6.1/package.conf Using package config file: /home/chris/.ghc/x86_64-linux-6.6.1/package.conf wired-in package base mapped to base-2.1.1 wired-in package rts mapped to rts-1.0 wired-in package haskell98 mapped to haskell98-1.0 wired-in package template-haskell mapped to template-haskell-2.1 Hsc static flags: -static *** Deleting temp files: Deleting: *** Deleting temp dirs: Deleting: ghc-6.6.1: no input files Usage: For basic information, try the `--help' option. chris@mars:~/dev/haskell/ffi$ gcc -v Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release x86_64-linux-gnu Thread model: posix gcc version 4.1.3 20070429 (prerelease) (Debian 4.1.2-5)
