Skip to content

Argument corruption in FFI with many arguments (maybe 64-bit related)

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)
Trac metadata
Trac field Value
Version 6.6.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler (FFI)
Test case
Differential revisions
BlockedBy
Related
Blocking
CC chris@cmears.id.au
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information