GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:51:04Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/7160C finalizers are reversed during GC2019-07-07T18:51:04ZBertram FelgenhauerC finalizers are reversed during GC(See also thread starting at http://www.haskell.org/pipermail/libraries/2012-August/018302.html )
The list of finalizers is reversed during GC (cf. `rts/sm/MarkWeak.c`), which may cause them to run in the wrong order.
The following prog...(See also thread starting at http://www.haskell.org/pipermail/libraries/2012-August/018302.html )
The list of finalizers is reversed during GC (cf. `rts/sm/MarkWeak.c`), which may cause them to run in the wrong order.
The following program reproduces this behaviour.
```
{-# LANGUAGE ForeignFunctionInterface, MagicHash #-}
import GHC.ForeignPtr
import GHC.Ptr
import System.Mem
-- one should really use own C function rather than this varargs one to avoid
-- possible ABI issues
foreign import ccall "&debugBelch" fun :: FunPtr (Ptr () -> Ptr () -> IO ())
new name = do
p <- newForeignPtr_ (Ptr name)
addForeignPtrFinalizerEnv fun (Ptr "finalizer 1 (%s)\n"#) p
addForeignPtrFinalizerEnv fun (Ptr "finalizer 2 (%s)\n"#) p
return p
main = do
p <- new "p"#
q <- new "q"#
r <- new "r"#
performGC -- collect p. finalizer order: 2, then 1.
print q
performGC -- collect q. finalizer order: 1, then 2.
-- expected order: 2, then 1.
print r
performGC -- collect r. finalizer order: 2, then 1.
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.1-rc1 |
| 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":"C finalizers are reversed during GC","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1-rc1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"(See also thread starting at http://www.haskell.org/pipermail/libraries/2012-August/018302.html )\r\n\r\nThe list of finalizers is reversed during GC (cf. {{{rts/sm/MarkWeak.c}}}), which may cause them to run in the wrong order.\r\nThe following program reproduces this behaviour.\r\n\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface, MagicHash #-}\r\nimport GHC.ForeignPtr\r\nimport GHC.Ptr\r\nimport System.Mem\r\n\r\n-- one should really use own C function rather than this varargs one to avoid\r\n-- possible ABI issues\r\nforeign import ccall \"&debugBelch\" fun :: FunPtr (Ptr () -> Ptr () -> IO ())\r\n\r\nnew name = do\r\n p <- newForeignPtr_ (Ptr name)\r\n addForeignPtrFinalizerEnv fun (Ptr \"finalizer 1 (%s)\\n\"#) p\r\n addForeignPtrFinalizerEnv fun (Ptr \"finalizer 2 (%s)\\n\"#) p\r\n return p\r\n\r\nmain = do\r\n p <- new \"p\"#\r\n q <- new \"q\"#\r\n r <- new \"r\"#\r\n performGC -- collect p. finalizer order: 2, then 1.\r\n print q\r\n performGC -- collect q. finalizer order: 1, then 2.\r\n -- expected order: 2, then 1.\r\n print r\r\n performGC -- collect r. finalizer order: 2, then 1.\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/6156Optimiser bug on linux-powerpc2019-07-07T18:51:54ZerikdOptimiser bug on linux-powerpcFound a small chunk of code in the cryptocipher package that when compiled and run, produces a difference result when optimised compared to compiling un-optimised.
Note this is only a problem with PowerPC. On x86-64 there is no differen...Found a small chunk of code in the cryptocipher package that when compiled and run, produces a difference result when optimised compared to compiling un-optimised.
Note this is only a problem with PowerPC. On x86-64 there is no difference in the output between the optimised version and the un-optimised version.
I have two simple files (Camellia.hs):
```
module Camellia where
import Data.Bits
import Data.Word
import Debug.Trace
fl :: Word64 -> Word64 -> Word64
fl fin sk =
let (x1, x2) = w64tow32 fin in
let (k1, k2) = w64tow32 sk in
let y2 = x2 `xor` ((x1 .&. k1) `rotateL` 1) in
let y1 = x1 `xor` (y2 .|. k2) in
trace (show fin ++ " " ++ show sk ++ " -> " ++ show (w32tow64 (y1, y2))) $ w32tow64 (y1, y2)
w64tow32 :: Word64 -> (Word32, Word32)
w64tow32 w = (fromIntegral (w `shiftR` 32), fromIntegral (w .&. 0xffffffff))
w32tow64 :: (Word32, Word32) -> Word64
w32tow64 (x1, x2) = ((fromIntegral x1) `shiftL` 32) .|. (fromIntegral x2)
```
and a main program (camellia-test.hs):
```
import Data.Word
import qualified Camellia as Camellia
a, b :: Word64
a = 1238988323332265734
b = 11185553392205053542
main :: IO ()
main =
putStrLn $ "Camellia.fl " ++ show a ++ " " ++ show b ++ " -> " ++ show (Camellia.fl a b)
```
I'm also using this Makefile:
```
TARGETS = camilla-test-std camilla-test-opt
check : $(TARGETS)
./camilla-test-std
./camilla-test-opt
clean :
make clean-temp-files
rm -f $(TARGETS)
clean-temp-files :
rm -f camilla-test.o camilla-test.hi Camellia.o Camellia.hi
camilla-test-opt : camilla-test.hs Camellia.hs
ghc -Wall -O2 --make -i:Tests $< -o $@
make clean-temp-files
camilla-test-std : camilla-test.hs Camellia.hs
ghc -Wall --make -i:Tests $< -o $@
make clean-temp-files
```
When I run the two programs I get:
```
./camilla-test-std
1238988323332265734 11185553392205053542 -> 18360184157246690566
Camellia.fl 1238988323332265734 11185553392205053542 -> 18360184157246690566
./camilla-test-opt
1238988323332265734 11185553392205053542 -> 3698434091925017862
Camellia.fl 38662 15974 -> 3698434091925017862
```
So there are two problems here:
a) Showing Word64 values is not working correctly in the optimised version.
b) The function Camelia.fl produces the wrong result in the optimised version.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.4.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Optimiser bug on linux-powerpc","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Found a small chunk of code in the cryptocipher package that when compiled and run, produces a difference result when optimised compared to compiling un-optimised.\r\n\r\nNote this is only a problem with PowerPC. On x86-64 there is no difference in the output between the optimised version and the un-optimised version.\r\n\r\nI have two simple files (Camellia.hs):\r\n\r\n{{{\r\nmodule Camellia where\r\n\r\nimport Data.Bits\r\nimport Data.Word\r\n\r\nimport Debug.Trace\r\n\r\nfl :: Word64 -> Word64 -> Word64\r\nfl fin sk =\r\n\tlet (x1, x2) = w64tow32 fin in\r\n\tlet (k1, k2) = w64tow32 sk in\r\n\tlet y2 = x2 `xor` ((x1 .&. k1) `rotateL` 1) in\r\n\tlet y1 = x1 `xor` (y2 .|. k2) in\r\n\ttrace (show fin ++ \" \" ++ show sk ++ \" -> \" ++ show (w32tow64 (y1, y2))) $ w32tow64 (y1, y2)\r\n\r\nw64tow32 :: Word64 -> (Word32, Word32)\r\nw64tow32 w = (fromIntegral (w `shiftR` 32), fromIntegral (w .&. 0xffffffff))\r\n\r\nw32tow64 :: (Word32, Word32) -> Word64\r\nw32tow64 (x1, x2) = ((fromIntegral x1) `shiftL` 32) .|. (fromIntegral x2)\r\n}}}\r\n\r\nand a main program (camellia-test.hs):\r\n\r\n{{{\r\n\r\nimport Data.Word\r\nimport qualified Camellia as Camellia\r\n\r\na, b :: Word64\r\na = 1238988323332265734\r\nb = 11185553392205053542\r\n\r\nmain :: IO ()\r\nmain =\r\n putStrLn $ \"Camellia.fl \" ++ show a ++ \" \" ++ show b ++ \" -> \" ++ show (Camellia.fl a b)\r\n\r\n}}}\r\n\r\nI'm also using this Makefile:\r\n\r\n{{{\r\nTARGETS = camilla-test-std camilla-test-opt\r\n\r\ncheck : $(TARGETS)\r\n\t./camilla-test-std\r\n\t./camilla-test-opt\r\n\r\nclean :\r\n\tmake clean-temp-files\r\n\trm -f $(TARGETS)\r\n\r\nclean-temp-files :\r\n\trm -f camilla-test.o camilla-test.hi Camellia.o Camellia.hi\r\n\r\ncamilla-test-opt : camilla-test.hs Camellia.hs\r\n\tghc -Wall -O2 --make -i:Tests $< -o $@\r\n\tmake clean-temp-files\r\n\r\ncamilla-test-std : camilla-test.hs Camellia.hs\r\n\tghc -Wall --make -i:Tests $< -o $@\r\n\tmake clean-temp-files\r\n}}}\r\n\r\nWhen I run the two programs I get:\r\n\r\n{{{\r\n./camilla-test-std\r\n1238988323332265734 11185553392205053542 -> 18360184157246690566\r\nCamellia.fl 1238988323332265734 11185553392205053542 -> 18360184157246690566\r\n./camilla-test-opt\r\n1238988323332265734 11185553392205053542 -> 3698434091925017862\r\nCamellia.fl 38662 15974 -> 3698434091925017862\r\n}}}\r\n\r\nSo there are two problems here:\r\n\r\na) Showing Word64 values is not working correctly in the optimised version.\r\n\r\nb) The function Camelia.fl produces the wrong result in the optimised version.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/6131-fprof-auto adds cost centers to INLINE functions2019-07-07T18:52:01Ztakano-akio-fprof-auto adds cost centers to INLINE functionsAccording to the Section 5.2 of User's Guide, -fprof-auto should add cost centers only to functions that are not marked INLINE. However GHC 7.4 doesn't respect this.
A simple example:
```
foo :: Integer -> Integer
foo x = x + 100
{-# I...According to the Section 5.2 of User's Guide, -fprof-auto should add cost centers only to functions that are not marked INLINE. However GHC 7.4 doesn't respect this.
A simple example:
```
foo :: Integer -> Integer
foo x = x + 100
{-# INLINE foo #-}
main = print $ loop (10000000::Int) 10000000000000000000000
where
loop 0 x = x
loop n x = loop (n-1) (foo x)
```
Compile and run this like:
```
% ghc -prof -fprof-auto -O2 test.hs
% ./test +RTS -p
% grep foo test.prof
```
And you will see 'foo' is listed as a cost center.
This happens with GHC 7.4.1 and 7.4.2-rc1
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.4.2-rc1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"-fprof-auto adds cost centers to INLINE functions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.2-rc1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"According to the Section 5.2 of User's Guide, -fprof-auto should add cost centers only to functions that are not marked INLINE. However GHC 7.4 doesn't respect this.\r\n\r\nA simple example:\r\n\r\n{{{\r\nfoo :: Integer -> Integer\r\nfoo x = x + 100\r\n{-# INLINE foo #-}\r\n\r\nmain = print $ loop (10000000::Int) 10000000000000000000000\r\n where\r\n loop 0 x = x\r\n loop n x = loop (n-1) (foo x)\r\n}}}\r\n\r\nCompile and run this like:\r\n\r\n{{{\r\n% ghc -prof -fprof-auto -O2 test.hs\r\n% ./test +RTS -p\r\n% grep foo test.prof\r\n}}}\r\n\r\nAnd you will see 'foo' is listed as a cost center.\r\n\r\nThis happens with GHC 7.4.1 and 7.4.2-rc1","type_of_failure":"OtherFailure","blocking":[]} -->7.4.3https://gitlab.haskell.org/ghc/ghc/-/issues/6116ctrl-c doesn't always work when entering text in ghci2019-07-07T18:52:06Zjudahjctrl-c doesn't always work when entering text in ghciWith ghci-7.5.20120519 (on Mac and probably also Linux): type some text, then press ctrl-c. Then type more text, and press ctrl-c again. The first time you press ctrl-c, it starts a new line. But the second time you press ctrl-c, nothing...With ghci-7.5.20120519 (on Mac and probably also Linux): type some text, then press ctrl-c. Then type more text, and press ctrl-c again. The first time you press ctrl-c, it starts a new line. But the second time you press ctrl-c, nothing happens. (Actually running code from within ghci resets this process.)
This is a regression from the behavior of ghci-7.4.1, where every time you press ctrl-C it caused a new line to be printed.
From my initial investigation, I think this was caused by ghc commit 206c8fc3ebd64c40ae09742fdea09ffd0f915d5c, which was used to fix #2786.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.5 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ctrl-c doesn't always work when entering text in ghci","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.5","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"With ghci-7.5.20120519 (on Mac and probably also Linux): type some text, then press ctrl-c. Then type more text, and press ctrl-c again. The first time you press ctrl-c, it starts a new line. But the second time you press ctrl-c, nothing happens. (Actually running code from within ghci resets this process.)\r\n\r\nThis is a regression from the behavior of ghci-7.4.1, where every time you press ctrl-C it caused a new line to be printed.\r\n\r\nFrom my initial investigation, I think this was caused by ghc commit 206c8fc3ebd64c40ae09742fdea09ffd0f915d5c, which was used to fix #2786. ","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/5870writeChan is not 100% exception-safe2019-07-07T18:53:11ZjoeyadamswriteChan is not 100% exception-safeControl.Concurrent.Chan.writeChan is currently implemented like this:
```
writeChan :: Chan a -> a -> IO ()
writeChan (Chan _ writeVar) val = do
new_hole <- newEmptyMVar
modifyMVar_ writeVar $ \old_hole -> do
putMVar old_hole (C...Control.Concurrent.Chan.writeChan is currently implemented like this:
```
writeChan :: Chan a -> a -> IO ()
writeChan (Chan _ writeVar) val = do
new_hole <- newEmptyMVar
modifyMVar_ writeVar $ \old_hole -> do
putMVar old_hole (ChItem val new_hole)
return new_hole
```
The problem is that modifyMVar_ restores the exception mask when it calls the callback. If an asynchronous exception is delivered immediately after the putMVar, the Chan's write end will be set to a filled hole, violating a key invariant.
I think it should be implemented like this:
```
writeChan :: Chan a -> a -> IO ()
writeChan (Chan _ writeVar) val = do
new_hole <- newEmptyMVar
mask_ $ do
old_hole <- takeMVar writeVar -- (1)
putMVar old_hole (ChItem val new_hole) -- (2)
putMVar writeVar new_hole -- (3)
```
This looks a bit naïve, but it should be atomic, at least in theory:
- (1) is interruptible. However, if it is interrupted, the MVar will remain intact.
- (2) is not interruptible, because old_hole is guaranteed to be empty. No other thread can fill it because we have taken exclusive access to writeVar.
- (3) is not interruptible, because we have taken exclusive access to writeVar.
This implementation has the added benefit of removing an exception handler, which should make it slightly faster.
readChan is okay, though:
```
readChan :: Chan a -> IO a
readChan (Chan readVar _) = do
modifyMVar readVar $ \read_end -> do
(ChItem val new_read_end) <- readMVar read_end
return (new_read_end, val)
```
If an exception is received immediately after the readMVar, then the read cursor will not be advanced, and the next call to readChan will simply read from that position again. Unfortunately, we can't get rid of the exception handler like we did with writeChan, because `readMVar read_end` is interruptible.
The attached patch changes the implementation of writeChan to the one shown above, and adds a comment to the definition of Chan about the write end's empty-hole invariant. I believe all of the Chan operations preserve this invariant, even the deprecated unGetChan and isEmptyChan.
I have not been able to create a test case where writeChan is interrupted between filling the hole and updating the write cursor. Perhaps it doesn't actually happen in practice, or perhaps it is extremely rare. But by my understanding of the semantics:
```
mask $ \restore -> do
thing1
restore $ putMVar ...
thing2
```
It is possible for an exception to arrive after the putMVar and before thing2.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.4.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"writeChan is not 100% exception-safe","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Control.Concurrent.Chan.writeChan is currently implemented like this:\r\n\r\n{{{\r\nwriteChan :: Chan a -> a -> IO ()\r\nwriteChan (Chan _ writeVar) val = do\r\n new_hole <- newEmptyMVar\r\n modifyMVar_ writeVar $ \\old_hole -> do\r\n putMVar old_hole (ChItem val new_hole)\r\n return new_hole\r\n}}}\r\n\r\nThe problem is that modifyMVar_ restores the exception mask when it calls the callback. If an asynchronous exception is delivered immediately after the putMVar, the Chan's write end will be set to a filled hole, violating a key invariant.\r\n\r\nI think it should be implemented like this:\r\n\r\n{{{\r\nwriteChan :: Chan a -> a -> IO ()\r\nwriteChan (Chan _ writeVar) val = do\r\n new_hole <- newEmptyMVar\r\n mask_ $ do\r\n old_hole <- takeMVar writeVar -- (1)\r\n putMVar old_hole (ChItem val new_hole) -- (2)\r\n putMVar writeVar new_hole -- (3)\r\n}}}\r\n\r\nThis looks a bit naïve, but it should be atomic, at least in theory:\r\n\r\n * (1) is interruptible. However, if it is interrupted, the MVar will remain intact.\r\n\r\n * (2) is not interruptible, because old_hole is guaranteed to be empty. No other thread can fill it because we have taken exclusive access to writeVar.\r\n\r\n * (3) is not interruptible, because we have taken exclusive access to writeVar.\r\n\r\nThis implementation has the added benefit of removing an exception handler, which should make it slightly faster.\r\n\r\nreadChan is okay, though:\r\n\r\n{{{\r\nreadChan :: Chan a -> IO a\r\nreadChan (Chan readVar _) = do\r\n modifyMVar readVar $ \\read_end -> do\r\n (ChItem val new_read_end) <- readMVar read_end\r\n return (new_read_end, val)\r\n}}}\r\n\r\nIf an exception is received immediately after the readMVar, then the read cursor will not be advanced, and the next call to readChan will simply read from that position again. Unfortunately, we can't get rid of the exception handler like we did with writeChan, because {{{readMVar read_end}}} is interruptible.\r\n\r\nThe attached patch changes the implementation of writeChan to the one shown above, and adds a comment to the definition of Chan about the write end's empty-hole invariant. I believe all of the Chan operations preserve this invariant, even the deprecated unGetChan and isEmptyChan.\r\n\r\nI have not been able to create a test case where writeChan is interrupted between filling the hole and updating the write cursor. Perhaps it doesn't actually happen in practice, or perhaps it is extremely rare. But by my understanding of the semantics:\r\n\r\n{{{\r\nmask $ \\restore -> do\r\n thing1\r\n restore $ putMVar ...\r\n thing2\r\n}}}\r\n\r\nIt is possible for an exception to arrive after the putMVar and before thing2.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.2Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/5865threadDelay is disrupted by system clock changes2019-07-07T18:53:13ZjoeyadamsthreadDelay is disrupted by system clock changesthreadDelay is sensitive to changes to the system clock. Two behaviors are observed:
- When the system clock is moved forward, threadDelay will timeout prematurely, because it thinks that amount of time elapsed.
- When the system clock ...threadDelay is sensitive to changes to the system clock. Two behaviors are observed:
- When the system clock is moved forward, threadDelay will timeout prematurely, because it thinks that amount of time elapsed.
- When the system clock is moved backward, threadDelay will take longer to complete, because it's waiting for the system clock to catch up.
Whether these behaviors are present depends on both the operating system and the use of -threaded. Here are the configurations I tested:
- ghc-7.4.1 Linux 64-bit: Disrupted by both forward and backward clock changes
- ghc-7.4.1 Linux 64-bit, **-threaded**: Disrupted only by backward clock changes
- ghc-7.2.2 Windows 32-bit: Not disrupted by clock changes (behaves correctly)
- ghc-7.2.2 Windows 32-bit, **-threaded**: Disrupted only by backward clock changes
To reproduce the problem, first compile the attached program. It uses System.Posix.Clock from the "clock" package to get the time, unaffected by system clock changes. Then run it. It will produce output like this:
```
0: 0s
1: 10s
```
Set the system clock forward by a minute. On Linux without -threaded, it will print something like this:
```
5: 50s
6: 52s
```
6 is printed 2 seconds after 5, because threadDelay didn't wait a full 10 seconds like it should have.
Now set the system clock backward by a minute. On Windows with -threaded, or on Linux with or without -threaded, it will print something like this:
```
3: 30s
4: 101s
```
4 is printed over a minute after 3, because threadDelay waited for the system clock to recover the time subtracted by changing the time.
For convenience, here's a way to fix the system clock on Linux after fiddling around with it:
```
sudo ntpdate pool.ntp.org
```
Digging through the source, each configuration seems to boil down to the following system calls:
- Linux: gettimeofday (via getourtimeofday in posix/Itimer.c)
- Linux, **-threaded**: gettimeofday, epoll_wait
- Windows: [Sleep](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx)
- Windows, **-threaded**: [GetSystemTimeAsFileTime](http://msdn.microsoft.com/en-us/library/windows/desktop/ms724397%28v=vs.85%29.aspx), [WaitForSingleObject](http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx)
Perhaps the calls to gettimeofday and GetSystemTimeAsFileTime should be replaced with monotonic time functions (i.e. ones not affected by system clock changes):
- Linux, FreeBSD: http://stackoverflow.com/q/211055/149391
- Mac OS X: http://stackoverflow.com/a/6725161/149391
- Windows: http://stackoverflow.com/q/211257/149391
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.4.1 |
| 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":"threadDelay is disrupted by system clock changes","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"threadDelay is sensitive to changes to the system clock. Two behaviors are observed:\r\n\r\n * When the system clock is moved forward, threadDelay will timeout prematurely, because it thinks that amount of time elapsed.\r\n\r\n * When the system clock is moved backward, threadDelay will take longer to complete, because it's waiting for the system clock to catch up.\r\n\r\nWhether these behaviors are present depends on both the operating system and the use of -threaded. Here are the configurations I tested:\r\n\r\n * ghc-7.4.1 Linux 64-bit: Disrupted by both forward and backward clock changes\r\n\r\n * ghc-7.4.1 Linux 64-bit, '''-threaded''': Disrupted only by backward clock changes\r\n\r\n * ghc-7.2.2 Windows 32-bit: Not disrupted by clock changes (behaves correctly)\r\n\r\n * ghc-7.2.2 Windows 32-bit, '''-threaded''': Disrupted only by backward clock changes\r\n\r\nTo reproduce the problem, first compile the attached program. It uses System.Posix.Clock from the \"clock\" package to get the time, unaffected by system clock changes. Then run it. It will produce output like this:\r\n\r\n{{{\r\n0: 0s\r\n1: 10s\r\n}}}\r\n\r\nSet the system clock forward by a minute. On Linux without -threaded, it will print something like this:\r\n\r\n{{{\r\n5: 50s\r\n6: 52s\r\n}}}\r\n\r\n6 is printed 2 seconds after 5, because threadDelay didn't wait a full 10 seconds like it should have.\r\n\r\nNow set the system clock backward by a minute. On Windows with -threaded, or on Linux with or without -threaded, it will print something like this:\r\n\r\n{{{\r\n3: 30s\r\n4: 101s\r\n}}}\r\n\r\n4 is printed over a minute after 3, because threadDelay waited for the system clock to recover the time subtracted by changing the time.\r\n\r\nFor convenience, here's a way to fix the system clock on Linux after fiddling around with it:\r\n\r\n{{{\r\nsudo ntpdate pool.ntp.org\r\n}}}\r\n\r\nDigging through the source, each configuration seems to boil down to the following system calls:\r\n\r\n * Linux: gettimeofday (via getourtimeofday in posix/Itimer.c)\r\n\r\n * Linux, '''-threaded''': gettimeofday, epoll_wait\r\n\r\n * Windows: [http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx Sleep]\r\n\r\n * Windows, '''-threaded''': [http://msdn.microsoft.com/en-us/library/windows/desktop/ms724397%28v=vs.85%29.aspx GetSystemTimeAsFileTime], [http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx WaitForSingleObject]\r\n\r\nPerhaps the calls to gettimeofday and GetSystemTimeAsFileTime should be replaced with monotonic time functions (i.e. ones not affected by system clock changes):\r\n\r\n * Linux, FreeBSD: http://stackoverflow.com/q/211055/149391\r\n\r\n * Mac OS X: http://stackoverflow.com/a/6725161/149391\r\n\r\n * Windows: http://stackoverflow.com/q/211257/149391","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/5843hGetBufSome blocks when all available input is buffered (on Windows only)2019-07-07T18:53:21ZjoeyadamshGetBufSome blocks when all available input is buffered (on Windows only)See the attached program. On Windows, it blocks on hGetSome.
If I take out the hGetLine and hWaitForInput, hGetSome does not block. If I add \<code\>hSetBuffering h NoBuffering\</code\>, hGetBufSome still blocks after hWaitForInput beca...See the attached program. On Windows, it blocks on hGetSome.
If I take out the hGetLine and hWaitForInput, hGetSome does not block. If I add \<code\>hSetBuffering h NoBuffering\</code\>, hGetBufSome still blocks after hWaitForInput because it does some buffering when it calls hLookAhead_.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"hGetBufSome blocks when all available input is buffered (on Windows only)","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"See the attached program. On Windows, it blocks on hGetSome.\r\n\r\nIf I take out the hGetLine and hWaitForInput, hGetSome does not block. If I add <code>hSetBuffering h NoBuffering</code>, hGetBufSome still blocks after hWaitForInput because it does some buffering when it calls hLookAhead_.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.2pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/5838integer overflow in rts/RtsUtils:heapOverflow()2019-07-07T18:53:23ZHerbert Valerio Riedelhvr@gnu.orginteger overflow in rts/RtsUtils:heapOverflow()When failing with a heap exhaustion, the RTS truncates the **reported** *current maximum heap size* modulo 2\^32, e.g.
```
$ ghc +RTS -M4G -RTS -e 'sum [1..]'
Heap exhausted;
Current maximum heap size is 0 bytes (0 MB);
use `+RTS -M<siz...When failing with a heap exhaustion, the RTS truncates the **reported** *current maximum heap size* modulo 2\^32, e.g.
```
$ ghc +RTS -M4G -RTS -e 'sum [1..]'
Heap exhausted;
Current maximum heap size is 0 bytes (0 MB);
use `+RTS -M<size>' to increase it.
```
This is most probably due to `OutOfHeapHook()` already being called with the truncated value from `heapOverflow()`:
```c
void
heapOverflow(void)
{
if (!heap_overflow)
{
/* don't fflush(stdout); WORKAROUND bug in Linux glibc */
OutOfHeapHook(0/*unknown request size*/,
RtsFlags.GcFlags.maxHeapSize * BLOCK_SIZE);
heap_overflow = rtsTrue;
}
}
```
which multiplies `RtsFlags.GcFlags.maxHeapSize` and `BLOCK_SIZE` whose type are 32-bit `unsigned int`s, causing the result to be wrapped again into an `unsigned int`, whereas the result should be upcasted to a `long unsigned int` (which at least on 64bit archs would be equivalent to a C99 `uint64_t`)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.2.2 |
| 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":"integer overflow in rts/RtsUtils:heapOverflow()","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When failing with a heap exhaustion, the RTS truncates the '''reported''' ''current maximum heap size'' modulo 2^32, e.g.\r\n\r\n{{{\r\n$ ghc +RTS -M4G -RTS -e 'sum [1..]'\r\nHeap exhausted;\r\nCurrent maximum heap size is 0 bytes (0 MB);\r\nuse `+RTS -M<size>' to increase it.\r\n}}}\r\n\r\nThis is most probably due to `OutOfHeapHook()` already being called with the truncated value from `heapOverflow()`:\r\n\r\n{{{\r\n#!c\r\nvoid\r\nheapOverflow(void)\r\n{\r\n if (!heap_overflow)\r\n {\r\n /* don't fflush(stdout); WORKAROUND bug in Linux glibc */\r\n OutOfHeapHook(0/*unknown request size*/,\r\n RtsFlags.GcFlags.maxHeapSize * BLOCK_SIZE);\r\n\r\n heap_overflow = rtsTrue;\r\n }\r\n}\r\n}}}\r\n\r\nwhich multiplies `RtsFlags.GcFlags.maxHeapSize` and `BLOCK_SIZE` whose type are 32-bit `unsigned int`s, causing the result to be wrapped again into an `unsigned int`, whereas the result should be upcasted to a `long unsigned int` (which at least on 64bit archs would be equivalent to a C99 `uint64_t`)\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.4.2Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/5626Miscompilation, exception omitted with -O2019-07-07T18:54:18Zmichal.palkaMiscompilation, exception omitted with -OFollowing program is miscompiled when compiled with `-O`.
```
module Main where
wrap x = [x]!!0
f :: [Int] -> a
f a = foldr (\b -> \c -> c) (undefined ()) (a ++ a) 0
main = do
print $ (f [] :: String)
print $ wrap $ (f [] :: Int)...Following program is miscompiled when compiled with `-O`.
```
module Main where
wrap x = [x]!!0
f :: [Int] -> a
f a = foldr (\b -> \c -> c) (undefined ()) (a ++ a) 0
main = do
print $ (f [] :: String)
print $ wrap $ (f [] :: Int)
print $ wrap $ (f [] :: (Int, Int, Int, Int))
```
The result of running it on my machine (Linux x86-64) is following:
```
"
1099511628032
zsh: segmentation fault ./test7
```
Looking at the Core it seems that instead of the expected `undefined` a partially-applied function is returned. GHC 7.3.20111022 was used for testing.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 7.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | michal.palka@poczta.fm |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Miscompilation, exception omitted with -O","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.3","keywords":["exception","miscompilation","strict","strictness"],"differentials":[],"test_case":"","architecture":"","cc":["michal.palka@poczta.fm"],"type":"Bug","description":"Following program is miscompiled when compiled with `-O`.\r\n{{{\r\nmodule Main where\r\n\r\nwrap x = [x]!!0\r\n\r\nf :: [Int] -> a\r\nf a = foldr (\\b -> \\c -> c) (undefined ()) (a ++ a) 0\r\n\r\nmain = do\r\n print $ (f [] :: String)\r\n print $ wrap $ (f [] :: Int)\r\n print $ wrap $ (f [] :: (Int, Int, Int, Int))\r\n}}}\r\n\r\nThe result of running it on my machine (Linux x86-64) is following:\r\n{{{\r\n\"\r\n1099511628032\r\nzsh: segmentation fault ./test7\r\n}}}\r\n\r\nLooking at the Core it seems that instead of the expected `undefined` a partially-applied function is returned. GHC 7.3.20111022 was used for testing.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/5625Code using seq has wrong strictness when unoptimised (too lazy)2019-07-07T18:54:18Zmichal.palkaCode using seq has wrong strictness when unoptimised (too lazy)The code code should crash with Prelude.undefined. When compiled with `-O` it behaves correctly, however with no optimisation (`-O0`) it prints `[0]` instead. Reading the Core suggests that the expression gets translated into `print (id ...The code code should crash with Prelude.undefined. When compiled with `-O` it behaves correctly, however with no optimisation (`-O0`) it prints `[0]` instead. Reading the Core suggests that the expression gets translated into `print (id [0])` when compiled with `-O0`. It was tested with GHC 7.3.20111022.
```
main = do
let a = \x -> seq undefined (+1)
print $ (a `seq` a [] `seq` id) [0]
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 7.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | michal.palka@poczta.fm |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Code using seq has wrong strictness when unoptimised (too lazy)","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.3","keywords":["lazy","seq","strict","strictness"],"differentials":[],"test_case":"","architecture":"","cc":["michal.palka@poczta.fm"],"type":"Bug","description":"The code code should crash with Prelude.undefined. When compiled with `-O` it behaves correctly, however with no optimisation (`-O0`) it prints `[0]` instead. Reading the Core suggests that the expression gets translated into `print (id [0])` when compiled with `-O0`. It was tested with GHC 7.3.20111022.\r\n\r\n{{{\r\nmain = do\r\n let a = \\x -> seq undefined (+1)\r\n print $ (a `seq` a [] `seq` id) [0]\r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/5614recompilation bug with -O2019-07-07T18:54:21Zgmi001recompilation bug with -ORecompilation with -O should also rebuild Main.hs in the attached test application consisting of Main.hs and X.hs.
Test case:
1) build the app with GHC --make -O Main.hs
2) run Main (output = B)
3) change and save in X.hs
> x = D {...Recompilation with -O should also rebuild Main.hs in the attached test application consisting of Main.hs and X.hs.
Test case:
1) build the app with GHC --make -O Main.hs
2) run Main (output = B)
3) change and save in X.hs
> x = D { f = B }
> to
> x = D { f = A }
4) rebuild the app with GHC --make -O Main.hs (recompiles only X.hs)
5) run Main (unexpected output = B)
6) force recompilation of both X.hs and Main.hs
7) run Main (output = A)
The bug is in -O.
A similar test with f :: String instead of f :: D2 runs without problems.
Problem is tested positive on WIN GHC 7.0.2, OpenSuse GHC 6.12.3, Mac OS X GHC 7.0.3 and GHC 7.2.1 (MAC?).
for more detail see http://sourceforge.net/apps/trac/ampersand/ticket/172.
the closed #1959 and #3166 describe similar problems.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"recompilation bug with -O","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":["recompilation"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Recompilation with -O should also rebuild Main.hs in the attached test application consisting of Main.hs and X.hs.\r\n\r\nTest case:\r\n\r\n1) build the app with GHC --make -O Main.hs\r\n\r\n2) run Main (output = B)\r\n\r\n3) change and save in X.hs\r\n\r\n x = D { f = B }\r\n\r\n to\r\n\r\n x = D { f = A }\r\n\r\n4) rebuild the app with GHC --make -O Main.hs (recompiles only X.hs) \r\n\r\n5) run Main (unexpected output = B)\r\n\r\n6) force recompilation of both X.hs and Main.hs\r\n\r\n7) run Main (output = A)\r\n\r\nThe bug is in -O.\r\nA similar test with f :: String instead of f :: D2 runs without problems.\r\n\r\nProblem is tested positive on WIN GHC 7.0.2, OpenSuse GHC 6.12.3, Mac OS X GHC 7.0.3 and GHC 7.2.1 (MAC?).\r\n\r\nfor more detail see http://sourceforge.net/apps/trac/ampersand/ticket/172.\r\n\r\nthe closed #1959 and #3166 describe similar problems.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/5594stdout is not flushed using custom main2019-07-07T18:54:35Zhandonsonstdout is not flushed using custom mainAccording to the [using your own main()](http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html#using-own-main) guide, Prepare two files.
main.c:
```
#include <stdio.h>
#include "HsFFI.h"
#ifdef __GLASGOW_HASKELL__
#incl...According to the [using your own main()](http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html#using-own-main) guide, Prepare two files.
main.c:
```
#include <stdio.h>
#include "HsFFI.h"
#ifdef __GLASGOW_HASKELL__
#include "Vomit_stub.h"
#endif
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
vomit();
hs_exit();
return 0;
}
```
Vomit.hs:
```
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE OverloadedStrings #-}
module Vomit where
import Data.ByteString
import Data.ByteString.Char8 ()
import Prelude hiding (putStr)
foreign export ccall vomit :: IO ()
vomit = putStr "Wrrreerrerek\n"
```
Compile the code:
```
$ ghc -c Vomit.hs
$ ghc --make -no-hs-main -optc-O main.c Vomit -o main
```
Run:
```
$ ./main
Wrrreerrerek
$
```
Looks fine. However:
```
$ ./main > output.txt
$ cat output.txt
$
```
output.txt is empty.
It seems when the output is done by some Haskell code called by a C code, and the stdout is redirected to a file, the output is not properly flushed. Changing Vomit.hs to:
```
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE OverloadedStrings #-}
module Vomit where
import Data.ByteString
import Data.ByteString.Char8 ()
import Prelude hiding (putStr)
import System.IO (hFlush, stdout)
foreign export ccall vomit :: IO ()
vomit = putStr "Wrrreerrerek\n" >> hFlush stdout
```
which manually flushes stdout, fixes the behavior.
Since hs_exit() on the C side is supposed to terminate the RTS and flush all output, this seems to be a bug.
Tested with GHC 7.0.4 on Debian GNU/Linux for x86.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.0.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"stdout is not flushed using custom main","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"According to the [http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html#using-own-main using your own main()] guide, Prepare two files.\r\n\r\nmain.c:\r\n\r\n{{{\r\n#include <stdio.h>\r\n#include \"HsFFI.h\"\r\n\r\n#ifdef __GLASGOW_HASKELL__\r\n#include \"Vomit_stub.h\"\r\n#endif\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n int i;\r\n\r\n hs_init(&argc, &argv);\r\n\r\n vomit();\r\n\r\n hs_exit();\r\n return 0;\r\n}\r\n}}}\r\n\r\nVomit.hs:\r\n\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\n{-# LANGUAGE OverloadedStrings #-}\r\n\r\nmodule Vomit where\r\n\r\nimport Data.ByteString\r\nimport Data.ByteString.Char8 ()\r\nimport Prelude hiding (putStr)\r\n\r\nforeign export ccall vomit :: IO ()\r\nvomit = putStr \"Wrrreerrerek\\n\"\r\n}}}\r\n\r\nCompile the code:\r\n\r\n{{{\r\n$ ghc -c Vomit.hs\r\n$ ghc --make -no-hs-main -optc-O main.c Vomit -o main\r\n}}}\r\n\r\nRun:\r\n\r\n{{{\r\n$ ./main\r\nWrrreerrerek\r\n$\r\n}}}\r\n\r\nLooks fine. However:\r\n\r\n{{{\r\n$ ./main > output.txt\r\n$ cat output.txt\r\n$\r\n}}}\r\n\r\noutput.txt is empty.\r\n\r\nIt seems when the output is done by some Haskell code called by a C code, and the stdout is redirected to a file, the output is not properly flushed. Changing Vomit.hs to:\r\n\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\n{-# LANGUAGE OverloadedStrings #-}\r\n\r\nmodule Vomit where\r\n\r\nimport Data.ByteString\r\nimport Data.ByteString.Char8 ()\r\nimport Prelude hiding (putStr)\r\n\r\nimport System.IO (hFlush, stdout)\r\n\r\nforeign export ccall vomit :: IO ()\r\nvomit = putStr \"Wrrreerrerek\\n\" >> hFlush stdout\r\n}}}\r\n\r\nwhich manually flushes stdout, fixes the behavior.\r\n\r\nSince hs_exit() on the C side is supposed to terminate the RTS and flush all output, this seems to be a bug.\r\n\r\nTested with GHC 7.0.4 on Debian GNU/Linux for x86.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/5587Code using seq has wrong strictness (too lazy) when optimised2020-02-26T21:26:10Zmichal.palkaCode using seq has wrong strictness (too lazy) when optimisedFollowing program prints `[1]` instead of crashing when compiled with `-O -fno-full-laziness`. Note that it's neccessary to use the extra definition `hiddenError` instead of calling `error` directly. The problem might be related to #5557...Following program prints `[1]` instead of crashing when compiled with `-O -fno-full-laziness`. Note that it's neccessary to use the extra definition `hiddenError` instead of calling `error` directly. The problem might be related to #5557, which, however, has already been fixed and optimisation is needed to trigger the current bug.
```
hiddenError = error "hidden error"
main = do
print $ seq (head (map (\a -> \b -> hiddenError) (hiddenError::[] Bool))) id [1]
```
I used GHC 7.3.20111022 for triggering this problem.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------------- |
| Version | 7.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | michal.palka@poczta.fm |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Code using seq has wrong strictness (too lazy) when optimised","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.3","keywords":["lazy","seq","strict","strictness"],"differentials":[],"test_case":"","architecture":"","cc":["michal.palka@poczta.fm"],"type":"Bug","description":"Following program prints `[1]` instead of crashing when compiled with `-O -fno-full-laziness`. Note that it's neccessary to use the extra definition `hiddenError` instead of calling `error` directly. The problem might be related to #5557, which, however, has already been fixed and optimisation is needed to trigger the current bug.\r\n\r\n{{{\r\nhiddenError = error \"hidden error\"\r\n\r\nmain = do\r\n print $ seq (head (map (\\a -> \\b -> hiddenError) (hiddenError::[] Bool))) id [1]\r\n}}}\r\n\r\nI used GHC 7.3.20111022 for triggering this problem.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/5558Deadlock using unsafePerformIO to create a global MVar2020-12-15T15:14:47ZBertram FelgenhauerDeadlock using unsafePerformIO to create a global MVarThe following program occasionally terminates with a BlockedIndefinitelyOnMVar exception. This is unexpected.
(According to SimonM, http://www.haskell.org/pipermail/glasgow-haskell-users/2011-October/021084.html)
```
import Control.Conc...The following program occasionally terminates with a BlockedIndefinitelyOnMVar exception. This is unexpected.
(According to SimonM, http://www.haskell.org/pipermail/glasgow-haskell-users/2011-October/021084.html)
```
import Control.Concurrent
import Control.Exception
import Control.Monad
import System.IO.Unsafe
main :: IO ()
main = do
-- evaluate lock -- adding this line fixes the problem
fin1 <- newEmptyMVar
fin2 <- newEmptyMVar
forkIO $ ping >>= putMVar fin1
forkIO $ ping >>= putMVar fin2
takeMVar fin1
takeMVar fin2
{-# NOINLINE lock #-}
lock :: MVar ()
lock = unsafePerformIO $ newMVar ()
ping = do
() <- takeMVar lock
putMVar lock ()
```
I tested the program as follows:
```
> ghc --make -rtsopts -threaded Main.hs; while ./Main +RTS -N; do true; done
Main: thread blocked indefinitely in an MVar operation
```
I'm using ghc 7.2.1.
```
> ghc --info
[("Project name","The Glorious Glasgow Haskell Compilation System")
,("GCC extra via C opts"," -fwrapv")
,("C compiler command","/usr/bin/gcc")
,("C compiler flags"," -fno-stack-protector")
,("ar command","/usr/bin/ar")
,("ar flags","q")
,("ar supports at file","YES")
,("touch command","touch")
,("dllwrap command","/bin/false")
,("windres command","/bin/false")
,("perl command","/usr/bin/perl")
,("Project version","7.2.1")
,("Booter version","7.0.3")
,("Stage","2")
,("Build platform","x86_64-unknown-linux")
,("Host platform","x86_64-unknown-linux")
,("Target platform","x86_64-unknown-linux")
,("Have interpreter","YES")
,("Object splitting supported","YES")
,("Have native code generator","YES")
,("Support SMP","YES")
,("Unregisterised","NO")
,("Tables next to code","YES")
,("RTS ways","l debug thr thr_debug thr_l thr_p dyn debug_dyn thr_dyn thr_debug_dyn")
,("Leading underscore","NO")
,("Debug on","False")
,("LibDir","/opt/ghc-7.2.1/lib/ghc-7.2.1")
,("Global Package DB","/opt/ghc-7.2.1/lib/ghc-7.2.1/package.conf.d")
,("Gcc Linker flags","[]")
,("Ld Linker flags","[]")
]
```
`/proc/cpuinfo` lists 4 Intel(R) Core(TM) i7 CPU M 620 @ 2.67GHz cores.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.2.1 |
| 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":"Deadlock using unsafePerformIO to create a global MVar","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following program occasionally terminates with a BlockedIndefinitelyOnMVar exception. This is unexpected.\r\n(According to SimonM, http://www.haskell.org/pipermail/glasgow-haskell-users/2011-October/021084.html)\r\n\r\n{{{\r\nimport Control.Concurrent\r\nimport Control.Exception\r\nimport Control.Monad\r\nimport System.IO.Unsafe\r\n\r\nmain :: IO ()\r\nmain = do\r\n -- evaluate lock -- adding this line fixes the problem\r\n\r\n fin1 <- newEmptyMVar\r\n fin2 <- newEmptyMVar\r\n\r\n forkIO $ ping >>= putMVar fin1\r\n forkIO $ ping >>= putMVar fin2\r\n\r\n takeMVar fin1\r\n takeMVar fin2\r\n\r\n{-# NOINLINE lock #-}\r\nlock :: MVar ()\r\nlock = unsafePerformIO $ newMVar ()\r\n\r\nping = do\r\n () <- takeMVar lock\r\n putMVar lock ()\r\n}}}\r\n\r\nI tested the program as follows:\r\n\r\n{{{\r\n> ghc --make -rtsopts -threaded Main.hs; while ./Main +RTS -N; do true; done\r\nMain: thread blocked indefinitely in an MVar operation\r\n}}}\r\n\r\nI'm using ghc 7.2.1.\r\n\r\n{{{\r\n> ghc --info\r\n [(\"Project name\",\"The Glorious Glasgow Haskell Compilation System\")\r\n ,(\"GCC extra via C opts\",\" -fwrapv\")\r\n ,(\"C compiler command\",\"/usr/bin/gcc\")\r\n ,(\"C compiler flags\",\" -fno-stack-protector\")\r\n ,(\"ar command\",\"/usr/bin/ar\")\r\n ,(\"ar flags\",\"q\")\r\n ,(\"ar supports at file\",\"YES\")\r\n ,(\"touch command\",\"touch\")\r\n ,(\"dllwrap command\",\"/bin/false\")\r\n ,(\"windres command\",\"/bin/false\")\r\n ,(\"perl command\",\"/usr/bin/perl\")\r\n ,(\"Project version\",\"7.2.1\")\r\n ,(\"Booter version\",\"7.0.3\")\r\n ,(\"Stage\",\"2\")\r\n ,(\"Build platform\",\"x86_64-unknown-linux\")\r\n ,(\"Host platform\",\"x86_64-unknown-linux\")\r\n ,(\"Target platform\",\"x86_64-unknown-linux\")\r\n ,(\"Have interpreter\",\"YES\")\r\n ,(\"Object splitting supported\",\"YES\")\r\n ,(\"Have native code generator\",\"YES\")\r\n ,(\"Support SMP\",\"YES\")\r\n ,(\"Unregisterised\",\"NO\")\r\n ,(\"Tables next to code\",\"YES\")\r\n ,(\"RTS ways\",\"l debug thr thr_debug thr_l thr_p dyn debug_dyn thr_dyn thr_debug_dyn\")\r\n ,(\"Leading underscore\",\"NO\")\r\n ,(\"Debug on\",\"False\")\r\n ,(\"LibDir\",\"/opt/ghc-7.2.1/lib/ghc-7.2.1\")\r\n ,(\"Global Package DB\",\"/opt/ghc-7.2.1/lib/ghc-7.2.1/package.conf.d\")\r\n ,(\"Gcc Linker flags\",\"[]\")\r\n ,(\"Ld Linker flags\",\"[]\")\r\n ]\r\n}}}\r\n\r\n{{{/proc/cpuinfo}}} lists 4 Intel(R) Core(TM) i7 CPU M 620 @ 2.67GHz cores.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/5557Code using seq has wrong strictness (too lazy)2019-07-07T18:54:45Zmichal.palkaCode using seq has wrong strictness (too lazy)Following snippet of code gets miscompiled regardless of optimisation level:
```
([seq (seq (tail ([]::[Int])) (\a -> error "aaa"))] !! 0) [1]
```
The result of printing the value is `[1]`, whereas the correct result should be throwing...Following snippet of code gets miscompiled regardless of optimisation level:
```
([seq (seq (tail ([]::[Int])) (\a -> error "aaa"))] !! 0) [1]
```
The result of printing the value is `[1]`, whereas the correct result should be throwing an error:
```
testModule: Prelude.tail: empty list
```
The same problem occurs if I try to run the code in GHCI.
Looking at the Core at -O0 suggests that the expression with two `seq`s gets transformed into the identity function, despite that `tail []` could (and will) crash. Since the problem is visible in Core, I mark this bug as independent of the architecture.
I tried it in GHC versions 7.2.1 and 7.3.20111013, which gave same wrong results.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Code using seq has wrong strictness (too lazy)","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":["lazy","seq","strict","strictness"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Following snippet of code gets miscompiled regardless of optimisation level:\r\n{{{\r\n([seq (seq (tail ([]::[Int])) (\\a -> error \"aaa\"))] !! 0) [1]\r\n}}}\r\n\r\nThe result of printing the value is `[1]`, whereas the correct result should be throwing an error:\r\n{{{\r\ntestModule: Prelude.tail: empty list\r\n}}}\r\n\r\nThe same problem occurs if I try to run the code in GHCI.\r\n\r\nLooking at the Core at -O0 suggests that the expression with two `seq`s gets transformed into the identity function, despite that `tail []` could (and will) crash. Since the problem is visible in Core, I mark this bug as independent of the architecture.\r\n\r\nI tried it in GHC versions 7.2.1 and 7.3.20111013, which gave same wrong results.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/5553sendWakeup error in simple test program with MVars and killThread2019-07-07T18:54:46ZbitsendWakeup error in simple test program with MVars and killThreadThe following test program causes a **sendWakeup** error to be printed. It happens rarely, not on every run of the program.
I'm running GHC 7.2.1 on a fairly old Linux 2.6.27 system.
Running it from the shell in a loop should cause it ...The following test program causes a **sendWakeup** error to be printed. It happens rarely, not on every run of the program.
I'm running GHC 7.2.1 on a fairly old Linux 2.6.27 system.
Running it from the shell in a loop should cause it to eventually display the error message. I found that by causing CPU activity (such as running "yes" in another terminal) while the shell loop below is running triggers the error.
```
$ ghc --make -Wall -O -threaded -rtsopts ghc_sendWakeup_bug.hs
$ while [ 1 ]; do ./ghc_sendWakeup_bug 40; done
ghc_sendWakeup_bug: sendWakeup: invalid argument (Bad file descriptor)
```
## ghc_sendWakeup_bug.hs
```
module Main
( startTest
, main
) where
import Control.Concurrent (ThreadId, forkIO, killThread, threadDelay)
import Control.Concurrent.MVar
import Control.Exception (finally, catch, SomeException, mask_)
import Control.Monad (when, replicateM_, forever)
import Prelude hiding (catch)
import System.Environment (getArgs, getProgName)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)
startClient :: IO ()
startClient = threadDelay (1000 * 10)
startTest :: Int -> IO ()
startTest numClients = do
-- Code adapted from:
-- http://hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/Control-Concurrent.html#g:12
children <- newMVar [] :: IO (MVar [MVar ()])
let forkChild :: IO () -> IO ThreadId
forkChild io = do
mvar <- newEmptyMVar
mask_ $ do
modifyMVar_ children (return . (mvar:))
forkIO (io `finally` putMVar mvar ())
waitForChildren :: IO ()
waitForChildren = do
cs <- takeMVar children
case cs of
[] -> return ()
m:ms -> do
putMVar children ms
takeMVar m
waitForChildren
serverThread <- forkIO $ forever (threadDelay 1000000)
replicateM_ numClients (forkChild startClient)
catch waitForChildren (printException "waitForChildren")
catch (killThread serverThread) (printException "killThread")
printException :: String -> SomeException -> IO ()
printException place ex =
hPutStrLn stderr $ "Error in " ++ place ++ ": " ++ show ex
main :: IO ()
main = do
args <- getArgs
when (length args /= 1) $ do
prog <- getProgName
hPutStrLn stderr $ "Usage: " ++ prog ++ " <numClients>"
exitFailure
let numClients = read (args !! 0)
startTest numClients
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.2.1 |
| 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":"sendWakeup error in simple test program with MVars and killThread","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following test program causes a '''sendWakeup''' error to be printed. It happens rarely, not on every run of the program.\r\n\r\nI'm running GHC 7.2.1 on a fairly old Linux 2.6.27 system.\r\n\r\nRunning it from the shell in a loop should cause it to eventually display the error message. I found that by causing CPU activity (such as running \"yes\" in another terminal) while the shell loop below is running triggers the error.\r\n\r\n{{{\r\n\r\n$ ghc --make -Wall -O -threaded -rtsopts ghc_sendWakeup_bug.hs\r\n$ while [ 1 ]; do ./ghc_sendWakeup_bug 40; done\r\nghc_sendWakeup_bug: sendWakeup: invalid argument (Bad file descriptor)\r\n\r\n}}}\r\n\r\n\r\n== ghc_sendWakeup_bug.hs ==\r\n\r\n{{{\r\n\r\nmodule Main\r\n ( startTest\r\n , main\r\n ) where\r\n\r\nimport Control.Concurrent (ThreadId, forkIO, killThread, threadDelay)\r\nimport Control.Concurrent.MVar\r\nimport Control.Exception (finally, catch, SomeException, mask_)\r\nimport Control.Monad (when, replicateM_, forever)\r\nimport Prelude hiding (catch)\r\nimport System.Environment (getArgs, getProgName)\r\nimport System.Exit (exitFailure)\r\nimport System.IO (hPutStrLn, stderr)\r\n\r\nstartClient :: IO ()\r\nstartClient = threadDelay (1000 * 10)\r\n\r\nstartTest :: Int -> IO ()\r\nstartTest numClients = do\r\n -- Code adapted from:\r\n -- http://hackage.haskell.org/packages/archive/base/4.4.0.0/doc/html/Control-Concurrent.html#g:12\r\n children <- newMVar [] :: IO (MVar [MVar ()])\r\n\r\n let forkChild :: IO () -> IO ThreadId\r\n forkChild io = do\r\n mvar <- newEmptyMVar\r\n mask_ $ do\r\n modifyMVar_ children (return . (mvar:))\r\n forkIO (io `finally` putMVar mvar ())\r\n waitForChildren :: IO ()\r\n waitForChildren = do\r\n cs <- takeMVar children\r\n case cs of\r\n [] -> return ()\r\n m:ms -> do\r\n putMVar children ms\r\n takeMVar m\r\n waitForChildren\r\n\r\n serverThread <- forkIO $ forever (threadDelay 1000000)\r\n\r\n replicateM_ numClients (forkChild startClient)\r\n catch waitForChildren (printException \"waitForChildren\")\r\n catch (killThread serverThread) (printException \"killThread\")\r\n\r\nprintException :: String -> SomeException -> IO ()\r\nprintException place ex =\r\n hPutStrLn stderr $ \"Error in \" ++ place ++ \": \" ++ show ex\r\n\r\nmain :: IO ()\r\nmain = do\r\n args <- getArgs\r\n when (length args /= 1) $ do\r\n prog <- getProgName\r\n hPutStrLn stderr $ \"Usage: \" ++ prog ++ \" <numClients>\"\r\n exitFailure\r\n let numClients = read (args !! 0)\r\n startTest numClients\r\n\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.2tibbetibbehttps://gitlab.haskell.org/ghc/ghc/-/issues/5438Wrong result for element check2019-07-07T18:55:15Zdaniel.is.fischerWrong result for element checkOn the [beginners](http://haskell.org/pipermail/beginners/2011-August/008422.html) list, Luca Ciciriello reported that
```
{-# LANGUAGE PArr #-}
{-# OPTIONS -fdph-seq #-}
module Main where
import Control.Parallel
import GHC.PArr
parA...On the [beginners](http://haskell.org/pipermail/beginners/2011-August/008422.html) list, Luca Ciciriello reported that
```
{-# LANGUAGE PArr #-}
{-# OPTIONS -fdph-seq #-}
module Main where
import Control.Parallel
import GHC.PArr
parArr :: [:String:]
parArr = [: "1", "2", "3", "4" :]
isElement :: String -> Bool
isElement x = x `elemP` parArr
main :: IO ()
main = do
putStrLn $ (show . isElement) "5"
```
prints True. Obviously it should print False. I've replicated the behaviour with 7.0.4 and 6.10.4 on 64-bit linux (Luca tested on Mac and Windows).
As far as I can tell, elemP no longer exists in dph, so I had to modify to test with HEAD, and
```
{-# LANGUAGE ParallelArrays #-}
{-# OPTIONS -fdph-seq #-}
module Main where
import GHC.PArr
import Data.Array.Parallel
parArr :: [:String:]
parArr = [: "1", "2", "3", "4" :]
isElement :: String -> Bool
isElement x = x `elemP1` parArr
where
elemP1 :: Eq a => a -> [:a:] -> Bool
elemP1 v ar = lengthP (filterP (== v) ar) /= 0
main :: IO ()
main = do
putStrLn $ (show . isElement) "5"
```
also prints True with HEAD, but prints False with 6.10.4 and 7.0.4 (with the necessary modifications, !ParallelArrays -\> PArr, don't import Data.Array.Parallel).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.0.4 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Data Parallel Haskell |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Wrong result for element check","status":"New","operating_system":"","component":"Data Parallel Haskell","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"On the [http://haskell.org/pipermail/beginners/2011-August/008422.html beginners] list, Luca Ciciriello reported that\r\n{{{\r\n{-# LANGUAGE PArr #-}\r\n{-# OPTIONS -fdph-seq #-}\r\n\r\nmodule Main where\r\n\r\nimport Control.Parallel\r\nimport GHC.PArr\r\n\r\nparArr :: [:String:]\r\nparArr = [: \"1\", \"2\", \"3\", \"4\" :]\r\n\r\nisElement :: String -> Bool\r\nisElement x = x `elemP` parArr\r\n\r\nmain :: IO ()\r\nmain = do\r\n putStrLn $ (show . isElement) \"5\"\r\n}}}\r\nprints True. Obviously it should print False. I've replicated the behaviour with 7.0.4 and 6.10.4 on 64-bit linux (Luca tested on Mac and Windows).\r\n\r\nAs far as I can tell, elemP no longer exists in dph, so I had to modify to test with HEAD, and\r\n{{{\r\n{-# LANGUAGE ParallelArrays #-}\r\n{-# OPTIONS -fdph-seq #-}\r\n\r\nmodule Main where\r\n\r\nimport GHC.PArr\r\nimport Data.Array.Parallel\r\n\r\nparArr :: [:String:]\r\nparArr = [: \"1\", \"2\", \"3\", \"4\" :]\r\n\r\nisElement :: String -> Bool\r\nisElement x = x `elemP1` parArr\r\n where\r\n elemP1 :: Eq a => a -> [:a:] -> Bool\r\n elemP1 v ar = lengthP (filterP (== v) ar) /= 0\r\n\r\nmain :: IO ()\r\nmain = do\r\n putStrLn $ (show . isElement) \"5\"\r\n}}}\r\nalso prints True with HEAD, but prints False with 6.10.4 and 7.0.4 (with the necessary modifications, !ParallelArrays -> PArr, don't import Data.Array.Parallel).","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1benlbenlhttps://gitlab.haskell.org/ghc/ghc/-/issues/5421<<loop>> in withMVar (reproducible, but with large test case)2019-07-07T18:55:26Zjmillikin<<loop>> in withMVar (reproducible, but with large test case)A user of one of my libraries is reporting that it fails with the message `<<loop>>` when compiled in GHC 7.2.1. The error is coming from `withMVar`, and is reproducible.
Unfortunately, the problem is \*very\* tricky to reproduce. Attem...A user of one of my libraries is reporting that it fails with the message `<<loop>>` when compiled in GHC 7.2.1. The error is coming from `withMVar`, and is reproducible.
Unfortunately, the problem is \*very\* tricky to reproduce. Attempting to debug it (such as adding print statements, re-ordering operations, or removing unrelated code) will cause it to vanish. Therefore, the test case I have attached is a full Cabal project with build instructions. Nearly every line of code is required, and changing or removing them hides the error again.
Changes which can hide the problem:
- Altering or removing the startup messages (even the version number).
- Removing unused attributes from types.
- Removing unused error checking.
- Using `_ <- char 'a'` instead of `void (char 'a')`.
- Moving a function from one module to another.
- Simplifying loops which only run over one element.
- Building it all at once with `--make`, and not a separate `cabal-dev install` step.
- Building 'Main' with `-O2`.7.4.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/5319MacOS X + executeFile + -threaded = "Operation not supported"2019-07-07T18:55:54ZPHOMacOS X + executeFile + -threaded = "Operation not supported"http://uninformed.org/index.cgi?v=1&a=1&p=16
http://lists.apple.com/archives/cocoa-dev/2005/Oct/msg00836.html
Mac OS X has an undocumented behavior concerning 'execve(2)' inside a
threaded process. If a process tries to call 'execve(2)'...http://uninformed.org/index.cgi?v=1&a=1&p=16
http://lists.apple.com/archives/cocoa-dev/2005/Oct/msg00836.html
Mac OS X has an undocumented behavior concerning 'execve(2)' inside a
threaded process. If a process tries to call 'execve(2)' and has more
than one native thread, the kernel returns 'EOPNOTSUPP'. This prevents
'executeFile' from working when the threaded runtime is used.
```
% ghci
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> System.Posix.Process.executeFile "/bin/sh" False [] Nothing
Loading package unix-2.4.2.0 ... linking ... done.
*** Exception: /bin/sh: executeFile: failed (Operation not supported)
Prelude>
Leaving GHCi.
% uname
Darwin
```
To work around this, we have to 'fork(2)' before calling 'execve(2)',
to make sure there is only a single active thread.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.0.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/unix |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"MacOS X + executeFile + -threaded = \"Operation not supported\"","status":"New","operating_system":"","component":"libraries/unix","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":["exec","thread,"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"http://uninformed.org/index.cgi?v=1&a=1&p=16\r\nhttp://lists.apple.com/archives/cocoa-dev/2005/Oct/msg00836.html\r\n\r\nMac OS X has an undocumented behavior concerning 'execve(2)' inside a\r\nthreaded process. If a process tries to call 'execve(2)' and has more\r\nthan one native thread, the kernel returns 'EOPNOTSUPP'. This prevents\r\n'executeFile' from working when the threaded runtime is used.\r\n\r\n{{{\r\n% ghci\r\nGHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help\r\nLoading package ghc-prim ... linking ... done.\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\nLoading package ffi-1.0 ... linking ... done.\r\nPrelude> System.Posix.Process.executeFile \"/bin/sh\" False [] Nothing\r\nLoading package unix-2.4.2.0 ... linking ... done.\r\n*** Exception: /bin/sh: executeFile: failed (Operation not supported)\r\nPrelude> \r\nLeaving GHCi.\r\n% uname\r\nDarwin\r\n}}}\r\n\r\nTo work around this, we have to 'fork(2)' before calling 'execve(2)',\r\nto make sure there is only a single active thread.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/5282Bizarre results from -P profiler on OS X2019-07-07T18:56:04ZbosBizarre results from -P profiler on OS XI'm trying to use the profiler to understand the performance of an application on OS X. I have a smallish benchmark that prints a lot of lines of text to `stdout`, and the numbers reported when I use `+RTS -P` are very different from wha...I'm trying to use the profiler to understand the performance of an application on OS X. I have a smallish benchmark that prints a lot of lines of text to `stdout`, and the numbers reported when I use `+RTS -P` are very different from what I see with my eyes.
The benchmark itself is quite simple:
https://github.com/mailrank/text-format/blob/master/benchmarks/Simple.hs
When I run it on the command line, it produces simple enough output:
```
$ time ./Simple one 500000 +RTS -P >/dev/null
500000 iterations in 2.6 secs (191.7 thousand/sec)
real 0m2.626s
user 0m2.586s
sys 0m0.030s
```
The time measured within the app and the wallclock time are both in agreement.
However, if I look at the `Simple.prof` file left behind afterwards, its numbers seem bizarre:
```
Mon Jun 27 11:35 2011 Time and Allocation Profiling Report (Final)
Simple +RTS -P -RTS one 500000
total time = 0.28 secs (14 ticks @ 20 ms)
total alloc = 2,200,395,720 bytes (excludes profiling overheads)
```
It reports a time of just 0.28 seconds, and the number of ticks it counts arithmetically agree with this.
I have other programs that suffer from the same discrepancy between wallclock measurement and what the profiler reports to me, such that I don't feel like I can trust the profiler at all here. I'm at a loss for what to do about this, though.
<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 | MacOS X |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Bizarre results from -P profiler on OS X","status":"New","operating_system":"MacOS X","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm trying to use the profiler to understand the performance of an application on OS X. I have a smallish benchmark that prints a lot of lines of text to `stdout`, and the numbers reported when I use `+RTS -P` are very different from what I see with my eyes.\r\n\r\nThe benchmark itself is quite simple:\r\n\r\nhttps://github.com/mailrank/text-format/blob/master/benchmarks/Simple.hs\r\n\r\nWhen I run it on the command line, it produces simple enough output:\r\n\r\n{{{\r\n$ time ./Simple one 500000 +RTS -P >/dev/null\r\n500000 iterations in 2.6 secs (191.7 thousand/sec)\r\n\r\nreal\t0m2.626s\r\nuser\t0m2.586s\r\nsys\t0m0.030s\r\n}}}\r\n\r\nThe time measured within the app and the wallclock time are both in agreement.\r\n\r\nHowever, if I look at the `Simple.prof` file left behind afterwards, its numbers seem bizarre:\r\n\r\n{{{\r\n Mon Jun 27 11:35 2011 Time and Allocation Profiling Report (Final)\r\n\r\n Simple +RTS -P -RTS one 500000\r\n\r\n total time = 0.28 secs (14 ticks @ 20 ms)\r\n total alloc = 2,200,395,720 bytes (excludes profiling overheads)\r\n}}}\r\n\r\nIt reports a time of just 0.28 seconds, and the number of ticks it counts arithmetically agree with this.\r\n\r\nI have other programs that suffer from the same discrepancy between wallclock measurement and what the profiler reports to me, such that I don't feel like I can trust the profiler at all here. I'm at a loss for what to do about this, though.","type_of_failure":"OtherFailure","blocking":[]} -->7.4.1Simon MarlowSimon Marlow