I am working on a C++ project that uses a Haskell DLL (GHC version is 8.0.1 x64). I've noticed, that the executing program consumes much memory. I investigated into the matter and that's what I've found out. Let's consider the following minimal example. Here is a little project that consists of three files.
HaskellExports.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module HaskellExports where
import Foreign.C.Types
import Foreign.StablePtr
foreign export ccall foo :: CInt -> IO (StablePtr Int)
foo :: CInt -> IO (StablePtr Int)
foo (CInt n) = newStablePtr (fromIntegral n)
Contains a function that is supposed to be called from a C/C++ code.
CWrapper.cpp
#define DLLExport extern "C" __declspec(dllexport)
DLLExport void* c_smth (const int num)
{
return 0;
}
I intentionally didn't include the real exports of the Haskell functions, because they make no difference to this example.
main.cpp
#include <Windows.h>
int main()
{
for (;;)
{
HINSTANCE module = ::LoadLibrary(L"HaskellExports.dll");
::FreeLibrary(module);
}
return 0;
}
Here, in an endless loop, I load the library and free it at once. Let's try to build the DLL in two different ways. First, let's not include the Haskell object file:
ghc -c HaskellExports.hs
ghc -c CWrapper.cpp
ghc -shared -no-hs-main -o HaskellExports.dll CWrapper.o
I've run the program and noticed (with the help of Windows process monitor), that the memory resources are captured and released properly.
Now let's also add the Haskell object file:
ghc -c HaskellExports.hs
ghc -c CWrapper.cpp
ghc -shared -no-hs-main -o HaskellExports.dll CWrapper.o HaskellExports.o
I've run the program again and noticed, that it consumes more and more memory in length of time with no intention to release it. This situation leads to a crash.
What am I doing wrong?
P.S. Further investigation showed that memory leak is caused only when HaskellExport.hs contains at least one foreign export function.