Trying to build a Win DLL with Haskell functions, I recognized some
strange things, which look to me like a bug in GHC's garbage collection.

Here's what I did:

1) First Trial:

* Define a module "Foo" (foo.hs):

module Foo where
foreign export stdcall foo :: Int -> IO Int
foo :: Int -> IO Int
foo n = return (length (f n))
f :: Int -> [Int]
f 0 = []
f n = n:(f (n-1))

* Write a def-File (foo.def):

EXPORTS
  foo@4

* Define the DllMain function in C (dllMain.c):

#include <windows.h>
#include <Rts.h>
static char* args[] = { "ghcDll" };
BOOL
STDCALL
DllMain
   ( HANDLE hModule
   , DWORD reason
   , void* reserved
   )
{
  if (reason == DLL_PROCESS_ATTACH) {
      /* By now, the RTS DLL should have been hoisted in, but we need to
start it up. */
      startupHaskell(1, args,NULL);
      return TRUE;
  }
  return TRUE;
}

* Compile it up:

ghc -c -static foo.hs -fglasgow-exts
ghc -c -static dllMain.c
ghc -static --mk-dll -optdll--def=foo.def -o foo.dll *.o -lHSrts

* Call "foo" from outside 3 times with the argument 2500:

The first two times the execution succeeds; but the third call ends with
an access violation error ("Zugriffsverletzung bei Adresse 69B89B99.
Lesen von Adresse FFFFFFFF.")

2) Second Trial:

* Write an addional caller-function in C (foo_caller.c), that
start/shuts down the RTS every time calling "foo".

#include "foo_stub.h"
#include "RtsAPI.h"
static char* args[] = { "ghcDll" };
StgInt __stdcall call_foo(StgInt a0)
{
  StgInt res;
  startupHaskell(1, args,NULL);
  res = foo(a0);
  shutdownHaskell();
  return res;
}

* Adjust the def file:

EXPORTS
  foo@4
  call_foo@4

* Compile it up:

ghc -c -static foo_caller.c
ghc -static --mk-dll -optdll--def=foo.def -o foo.dll *.o -lHSrts

* Call "call_foo" from outside with the argument 2500:

Now everything seems to be okay, the call can be repeated again and
again without any error.

I use GHC 4.08.1 with cygwin 1.1. - I recognized this kind of error also
when compiling with GHC4.05.

What to do about this?
Christian

foo.hs

foo_caller.c

foo.def

dllMain.c

Reply via email to