GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:04:04Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/15574C wrappers for Haskell foreign exports don't have finalizers (causes memory l...2019-07-07T18:04:04ZValoisaC wrappers for Haskell foreign exports don't have finalizers (causes memory leak).For each foreign export RTS creates a static C wrapper, which is initialized on `DLL_PROCESS_ATTACH`, but it has no finalizer/destructor to be called during `DLL_PROCESS_DETACH`. So it will stay alive till the program termination. That's...For each foreign export RTS creates a static C wrapper, which is initialized on `DLL_PROCESS_ATTACH`, but it has no finalizer/destructor to be called during `DLL_PROCESS_DETACH`. So it will stay alive till the program termination. That's why if one uses a Haskell DLL in their C/C++ project, \*\*consumed memory is not fully released after freeing the library\*\*.
\[\[br\]\]\[\[br\]\]
There are four files attached to this ticket.
- \*\*HaskellExports.hs\*\* contains exact one foreign export function;
- \*\*CWrapper.cpp\*\* is supposed to contain wrappers to the Haskell functions, described in *HaskellExports.hs*, but it doesn't because they make no difference;
- \*\*main.cpp\*\*: here in an endless loop the DLL (built with the help of the script below) is loaded and freed at once. Launched program is crashed in a while (because it runs out of memory);
- \*\*build.sh\*\* is a script for building the library.
\[\[br\]\]
The main program was built with MSVC 2015.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.0.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (FFI) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"C wrappers for Haskell foreign exports don't have finalizers (causes memory leak).","status":"New","operating_system":"","component":"Compiler (FFI)","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"For each foreign export RTS creates a static C wrapper, which is initialized on {{{DLL_PROCESS_ATTACH}}}, but it has no finalizer/destructor to be called during {{{DLL_PROCESS_DETACH}}}. So it will stay alive till the program termination. That's why if one uses a Haskell DLL in their C/C++ project, **consumed memory is not fully released after freeing the library**.\r\n[[br]][[br]]\r\nThere are four files attached to this ticket. \r\n* **HaskellExports.hs** contains exact one foreign export function;\r\n* **CWrapper.cpp** is supposed to contain wrappers to the Haskell functions, described in ''HaskellExports.hs'', but it doesn't because they make no difference;\r\n* **main.cpp**: here in an endless loop the DLL (built with the help of the script below) is loaded and freed at once. Launched program is crashed in a while (because it runs out of memory);\r\n* **build.sh** is a script for building the library.\r\n[[br]]\r\nThe main program was built with MSVC 2015.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/5611Asynchronous exception discarded after safe FFI call2019-07-07T18:54:23ZjoeyadamsAsynchronous exception discarded after safe FFI call**Note:** This bug appears to be fixed already, as it does not appear with GHC 7.2.1 . I'm submitting a bug report anyway, to document its presence.
The bug is: when an asynchronous exception is thrown to a thread making a (safe) foreig...**Note:** This bug appears to be fixed already, as it does not appear with GHC 7.2.1 . I'm submitting a bug report anyway, to document its presence.
The bug is: when an asynchronous exception is thrown to a thread making a (safe) foreign call, the thread throwing the exception blocks like it should, but then the exception isn't actually delivered. For example:
```haskell
{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Concurrent
import Foreign.C
import System.IO
foreign import ccall safe "unistd.h sleep"
sleep :: CUInt -> IO CUInt
main :: IO ()
main = do
hSetBuffering stdout LineBuffering
tid <- forkIO $ do
putStrLn "child: Sleeping"
_ <- sleep 1
-- The following lines should not happen after the killThread from the
-- parent thread completes. However, they do...
putStrLn "child: Done sleeping"
threadDelay 1000000
putStrLn "child: Done waiting"
threadDelay 100000
putStrLn $ "parent: Throwing exception to thread " ++ show tid
throwTo tid $ userError "Exception delivered successfully"
putStrLn "parent: Done throwing exception"
threadDelay 2000000
```
When the bug is present, the program prints:
```
child: Sleeping
parent: Throwing exception to thread ThreadId 4
child: Done sleeping
parent: Done throwing exception
child: Done waiting
```
"child: Done waiting" should not be printed after completion of the throwTo, and the exception message should appear. On GHC 7.2.1, the program prints:
```
child: Sleeping
parent: Throwing exception to thread ThreadId 4
parent: Done throwing exception
ffi-sleep: user error (Exception delivered successfully)
```
This bug has been reproduced in GHC 7.0.3, on both Linux and Windows. It has also been reproduced on GHC 7.0.4.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.0.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Asynchronous exception discarded after safe FFI call","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":["FFI,","exception"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"'''Note:''' This bug appears to be fixed already, as it does not appear with GHC 7.2.1 . I'm submitting a bug report anyway, to document its presence.\r\n\r\nThe bug is: when an asynchronous exception is thrown to a thread making a (safe) foreign call, the thread throwing the exception blocks like it should, but then the exception isn't actually delivered. For example:\r\n\r\n{{{\r\n\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\n\r\nimport Control.Concurrent\r\nimport Foreign.C\r\nimport System.IO\r\n\r\nforeign import ccall safe \"unistd.h sleep\"\r\n sleep :: CUInt -> IO CUInt\r\n\r\nmain :: IO ()\r\nmain = do\r\n hSetBuffering stdout LineBuffering\r\n\r\n tid <- forkIO $ do\r\n putStrLn \"child: Sleeping\"\r\n _ <- sleep 1\r\n\r\n -- The following lines should not happen after the killThread from the\r\n -- parent thread completes. However, they do...\r\n putStrLn \"child: Done sleeping\"\r\n threadDelay 1000000\r\n putStrLn \"child: Done waiting\"\r\n\r\n threadDelay 100000\r\n putStrLn $ \"parent: Throwing exception to thread \" ++ show tid\r\n throwTo tid $ userError \"Exception delivered successfully\"\r\n putStrLn \"parent: Done throwing exception\"\r\n\r\n threadDelay 2000000\r\n}}}\r\n\r\nWhen the bug is present, the program prints:\r\n\r\n{{{\r\nchild: Sleeping\r\nparent: Throwing exception to thread ThreadId 4\r\nchild: Done sleeping\r\nparent: Done throwing exception\r\nchild: Done waiting\r\n}}}\r\n\r\n\"child: Done waiting\" should not be printed after completion of the throwTo, and the exception message should appear. On GHC 7.2.1, the program prints:\r\n\r\n{{{\r\nchild: Sleeping\r\nparent: Throwing exception to thread ThreadId 4\r\nparent: Done throwing exception\r\nffi-sleep: user error (Exception delivered successfully)\r\n}}}\r\n\r\nThis bug has been reproduced in GHC 7.0.3, on both Linux and Windows. It has also been reproduced on GHC 7.0.4.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1Simon MarlowSimon Marlow