Opened 10 years ago

Closed 10 years ago

Last modified 6 years ago

#732 closed bug (fixed)

Error in shutdownHaskell() in Win32 DLL

Reported by: cschmidt@… Owned by:
Priority: normal Milestone: 6.4.2
Component: Runtime System Version: 6.4.1
Keywords: Cc:
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):


If an exception occurs in a Windows DLL produced by GHC, the following error message appears:

ghcDll: internal error: too many hs_exit()s
    Please report this as a bug to [email protected],

How to reproduce

  1. Make a Haskell DLL using the enclosed Dll.hs and dllMain.c, e.g.
    ghc -c Dll.hs -fglasgow-exts
    ghc -c dllMain.c
    ghc --mk-dll -o test.dll Dll.o Dll_stub.o dllMain.o
  1. Generate an export library for the DLL, e.g.
    lib /DEF:test.def /MACHINE:x86 /OUT:test.lib
  1. Compile the executable with Visual C++ and run it.
    cl -c testdll.cpp
    link testdll.obj test.lib /OUT:testdll.exe

Note: if I comment out the shutdownHaskell() call from dllMain.c (the line marked with /*/), it works fine.

Kind regards,


--- Dll.hs ---

module Dll (test) where

foreign export ccall test :: IO ()

test = error "Exception occurred"

--- dllMain.c ---

#include <windows.h>
#include <Rts.h>

extern void __stginit_Dll(void);

static char* args[] = { "ghcDll", NULL };

   ( HANDLE hModule
   , DWORD reason
   , void* reserved
  if (reason == DLL_PROCESS_ATTACH) {
      startupHaskell(1, args, __stginit_Dll);
      return TRUE;
  } else if (reason == DLL_PROCESS_DETACH) {
/***/   shutdownHaskell();
  return TRUE;

--- test.def ---


--- testdll.cpp ---

extern "C" void test();

int main() {
	return 0;

Change History (4)

comment:1 Changed 10 years ago by simonmar

I've made the error a warning instead.

Basically the situation is this: it is your responsibility to include exception handlers in foreign exported functions and to return appropriate error values. The only thing that the runtime can do in the event that a foreign exported function raises an exception is to terminate with a fatal error; there's no way to return a value to the caller, because we don't know what value to return.

In your example, the runtime had terminated, and your DLL code attempted to shut it down again. There's no reason this really has to be a fatal error, though.

comment:2 Changed 10 years ago by simonmar

  • Resolution set to fixed
  • Status changed from new to closed

comment:3 Changed 7 years ago by simonmar

  • Architecture changed from Unknown to Unknown/Multiple

comment:4 Changed 6 years ago by simonmar

  • difficulty changed from Easy (1 hr) to Easy (less than 1 hour)
Note: See TracTickets for help on using tickets.