GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:43:46Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/8726integer-gmp division regression2019-07-07T18:43:46Zerikdinteger-gmp division regressionWith ghc 7.6.3:
```
ghci> quotRem 0x10000000000000001 (-0x100000)
(-17592186044416,1)
ghci> quotRem 0x10000001 (-0x100000)
(-256,1)
```
with ghc 7.7
```
ghci> quotRem 0x10000000000000001 (-0x100000)
(-17592186044416,-1)
ghci> quotRem ...With ghc 7.6.3:
```
ghci> quotRem 0x10000000000000001 (-0x100000)
(-17592186044416,1)
ghci> quotRem 0x10000001 (-0x100000)
(-256,1)
```
with ghc 7.7
```
ghci> quotRem 0x10000000000000001 (-0x100000)
(-17592186044416,-1)
ghci> quotRem 0x10000001 (-0x100000)
(-256,1)
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 7.7 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries (other) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"integer-gmp division regression","status":"New","operating_system":"","component":"libraries (other)","related":[],"milestone":"7.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":["Integer"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"With ghc 7.6.3:\r\n\r\n{{{\r\nghci> quotRem 0x10000000000000001 (-0x100000)\r\n(-17592186044416,1)\r\nghci> quotRem 0x10000001 (-0x100000)\r\n(-256,1)\r\n}}}\r\n\r\nwith ghc 7.7\r\n\r\n{{{\r\nghci> quotRem 0x10000000000000001 (-0x100000)\r\n(-17592186044416,-1)\r\nghci> quotRem 0x10000001 (-0x100000)\r\n(-256,1)\r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Herbert Valerio Riedelhvr@gnu.orgHerbert Valerio Riedelhvr@gnu.orghttps://gitlab.haskell.org/ghc/ghc/-/issues/8291unloadObj doesn't work, unloaded_objects list keeps growing in size2019-07-07T18:45:42ZEdward Z. YangunloadObj doesn't work, unloaded_objects list keeps growing in sizeShows up as the linker_unload test going very slowly and triggering the timeout on my box. Verified by looking at the unloaded_objects list, which contains multiple copies of Test.o. I haven't investigated any further.
<details><summary...Shows up as the linker_unload test going very slowly and triggering the timeout on my box. Verified by looking at the unloaded_objects list, which contains multiple copies of Test.o. I haven't investigated any further.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.7 |
| 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":"unloadObj doesn't work on Mac OS X","status":"New","operating_system":"MacOS X","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Shows up as the linker_unload test going very slowly and triggering the timeout on my box. Verified by looking at the unloaded_objects list, which contains multiple copies of Test.o. I haven't investigated any further.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/8083setNumCapabilities broken in HEAD2019-07-07T18:46:34ZparcssetNumCapabilities broken in HEAD```haskell
import GHC.Conc
import Control.Monad
main :: IO ()
main = do
n <- getNumCapabilities
when (n == 1) $ setNumCapabilities 2
print ()
```
One would expect this program to print () just once, but when compiled with -...```haskell
import GHC.Conc
import Control.Monad
main :: IO ()
main = do
n <- getNumCapabilities
when (n == 1) $ setNumCapabilities 2
print ()
```
One would expect this program to print () just once, but when compiled with -O or -O2 it prints () repeatedly and indefinitely!
This doesn't happen on GHC 7.6.2 or 7.4.1, only on HEAD.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.7 |
| 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":"setNumCapabilities broken in HEAD","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\n#!haskell\r\nimport GHC.Conc\r\nimport Control.Monad\r\n\r\nmain :: IO ()\r\nmain = do\r\n n <- getNumCapabilities\r\n when (n == 1) $ setNumCapabilities 2\r\n print ()\r\n}}}\r\n\r\nOne would expect this program to print () just once, but when compiled with -O or -O2 it prints () repeatedly and indefinitely!\r\n\r\nThis doesn't happen on GHC 7.6.2 or 7.4.1, only on HEAD.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/7163nofib/real/gg is miscompiled at -O12019-07-07T18:51:03ZMichal Terepetanofib/real/gg is miscompiled at -O1I've noticed that ```nofib/real/gg``` fails (output mismatch) and after reducing
the problem I've got the following small example (the trace expressions can also
be removed):
```
module Main where
import Debug.Trace
main = d...I've noticed that ```nofib/real/gg``` fails (output mismatch) and after reducing
the problem I've got the following small example (the trace expressions can also
be removed):
```
module Main where
import Debug.Trace
main = do
putStrLn $ printFloat 100
printFloat :: Float -> String
printFloat x = f (show (round (x*10)))
where
f "0" = trace "case 0" "0"
f _ = trace "case _" $ show (round x)
}}}
compiling it with current HEAD:
{{{
> ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O0 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
> ./Test
case _
100
> ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O1 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
> ./Test
case _
1000
> ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O2 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
> ./Test
case _
100
}}}
Note that with ```-O1``` the output is 1000! It seems that the bug is either in
the old codegen or the new one does not trigger it:
{{{
> ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O1 -fnew-codegen Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
> ./Test
case _
100
```
I've also looked at assembly and the only thing that I've noticed is that two
instructions are in different order when compiling with ```O1```:
```
Main.$wprintFloat_info:
_c28u:
leaq -40(%rbp),%rax
cmpq %r15,%rax
jb _c2aV
mulss _n2aX(%rip),%xmm1 <--- !
movss %xmm1,%xmm0 <--- !
subq $8,%rsp
movl $1,%eax
call rintFloat
addq $8,%rsp
movss %xmm1,-8(%rbp)
movss %xmm0,%xmm1
movq $s23Y_info,-16(%rbp)
addq $-16,%rbp
jmp stg_decodeFloat_Int#
_c2aV:
movl $Main.$wprintFloat_closure,%ebx
jmp *-8(%r13)
.size Main.$wprintFloat_info, .-Main.$wprintFloat_info
.section .rodata
.align 8
.align 4
}}}
and ```O2```:
{{{
Main.$wprintFloat_info:
_c28R:
leaq -40(%rbp),%rax
cmpq %r15,%rax
jb _c2aX
movss %xmm1,%xmm0 <--- !
mulss _n2aZ(%rip),%xmm0 <--- !
subq $8,%rsp
movl $1,%eax
call rintFloat
addq $8,%rsp
movss %xmm1,-8(%rbp)
movss %xmm0,%xmm1
movq $s24l_info,-16(%rbp)
addq $-16,%rbp
jmp stg_decodeFloat_Int#
_c2aX:
movl $Main.$wprintFloat_closure,%ebx
jmp *-8(%r13)
.size Main.$wprintFloat_info, .-Main.$wprintFloat_info
.section .rodata
.align 8
.align 4
}}}
If I read this right, in ```O1``` case the ```xmm1``` register will contain 1000
(1000 * 10) and this value will be stored on the stack, whereas the ```O2```
version first moves the value from ```xmm1``` to ```xmm0``` and only then
multiplies it (and also stores ```xmm1``` on the stack but this time it should
be equal to 100). So if the value stored on the stack is subsequently used, it
would explain the difference between the two programs.
For the record this is on x86_64 Linux and the GHC version used is:
{{{
> ~/dev/ghc-clean/inplace/bin/ghc-stage2 --version
The Glorious Glasgow Haskell Compilation System, version 7.7.20120816
```
Everything works as expected on GHC-7.4.2.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.7 |
| 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":"nofib/real/gg is miscompiled at -O1","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I've noticed that ```nofib/real/gg``` fails (output mismatch) and after reducing\r\nthe problem I've got the following small example (the trace expressions can also\r\nbe removed):\r\n{{{\r\n module Main where\r\n\r\n import Debug.Trace\r\n\r\n main = do\r\n putStrLn $ printFloat 100\r\n\r\n printFloat :: Float -> String\r\n printFloat x = f (show (round (x*10)))\r\n where\r\n f \"0\" = trace \"case 0\" \"0\"\r\n f _ = trace \"case _\" $ show (round x)\r\n }}}\r\ncompiling it with current HEAD:\r\n{{{\r\n > ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O0 Test.hs\r\n [1 of 1] Compiling Main ( Test.hs, Test.o )\r\n Linking Test ...\r\n > ./Test\r\n case _\r\n 100\r\n > ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O1 Test.hs\r\n [1 of 1] Compiling Main ( Test.hs, Test.o )\r\n Linking Test ...\r\n > ./Test\r\n case _\r\n 1000\r\n > ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O2 Test.hs\r\n [1 of 1] Compiling Main ( Test.hs, Test.o )\r\n Linking Test ...\r\n > ./Test\r\n case _\r\n 100\r\n }}}\r\nNote that with ```-O1``` the output is 1000! It seems that the bug is either in\r\nthe old codegen or the new one does not trigger it:\r\n{{{\r\n > ~/dev/ghc-clean/inplace/bin/ghc-stage2 -fforce-recomp -O1 -fnew-codegen Test.hs\r\n [1 of 1] Compiling Main ( Test.hs, Test.o )\r\n Linking Test ...\r\n > ./Test\r\n case _\r\n 100\r\n}}}\r\nI've also looked at assembly and the only thing that I've noticed is that two\r\ninstructions are in different order when compiling with ```O1```:\r\n{{{\r\n Main.$wprintFloat_info:\r\n _c28u:\r\n leaq -40(%rbp),%rax\r\n cmpq %r15,%rax\r\n jb _c2aV\r\n mulss _n2aX(%rip),%xmm1 <--- !\r\n movss %xmm1,%xmm0 <--- !\r\n subq $8,%rsp\r\n movl $1,%eax\r\n call rintFloat\r\n addq $8,%rsp\r\n movss %xmm1,-8(%rbp)\r\n movss %xmm0,%xmm1\r\n movq $s23Y_info,-16(%rbp)\r\n addq $-16,%rbp\r\n jmp stg_decodeFloat_Int#\r\n _c2aV:\r\n movl $Main.$wprintFloat_closure,%ebx\r\n jmp *-8(%r13)\r\n .size Main.$wprintFloat_info, .-Main.$wprintFloat_info\r\n .section .rodata\r\n .align 8\r\n .align 4\r\n }}}\r\nand ```O2```:\r\n{{{\r\n Main.$wprintFloat_info:\r\n _c28R:\r\n leaq -40(%rbp),%rax\r\n cmpq %r15,%rax\r\n jb _c2aX\r\n movss %xmm1,%xmm0 <--- !\r\n mulss _n2aZ(%rip),%xmm0 <--- !\r\n subq $8,%rsp\r\n movl $1,%eax\r\n call rintFloat\r\n addq $8,%rsp\r\n movss %xmm1,-8(%rbp)\r\n movss %xmm0,%xmm1\r\n movq $s24l_info,-16(%rbp)\r\n addq $-16,%rbp\r\n jmp stg_decodeFloat_Int#\r\n _c2aX:\r\n movl $Main.$wprintFloat_closure,%ebx\r\n jmp *-8(%r13)\r\n .size Main.$wprintFloat_info, .-Main.$wprintFloat_info\r\n .section .rodata\r\n .align 8\r\n .align 4\r\n }}}\r\nIf I read this right, in ```O1``` case the ```xmm1``` register will contain 1000\r\n(1000 * 10) and this value will be stored on the stack, whereas the ```O2```\r\nversion first moves the value from ```xmm1``` to ```xmm0``` and only then\r\nmultiplies it (and also stores ```xmm1``` on the stack but this time it should\r\nbe equal to 100). So if the value stored on the stack is subsequently used, it\r\nwould explain the difference between the two programs.\r\n\r\nFor the record this is on x86_64 Linux and the GHC version used is:\r\n{{{\r\n> ~/dev/ghc-clean/inplace/bin/ghc-stage2 --version\r\nThe Glorious Glasgow Haskell Compilation System, version 7.7.20120816\r\n}}}\r\nEverything works as expected on GHC-7.4.2.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Ian Lynagh <igloo@earth.li>Ian Lynagh <igloo@earth.li>https://gitlab.haskell.org/ghc/ghc/-/issues/8741`System.Directory.getPermissions` fails on read-only filesystem2019-07-07T18:43:42ZHerbert Valerio Riedelhvr@gnu.org`System.Directory.getPermissions` fails on read-only filesystemAlain O'Dea reports in an [email](http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/21078) that:
```
Prelude> System.Directory.getPermissions "/usr/bin/ld"
*** Exception: /usr/bin/ld: fileAccess: permission denied (Read-only ...Alain O'Dea reports in an [email](http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/21078) that:
```
Prelude> System.Directory.getPermissions "/usr/bin/ld"
*** Exception: /usr/bin/ld: fileAccess: permission denied (Read-only file system)
```
> That seems wrong.
>
> An `access(*, W_OK)` syscall by design should return `EROFS` on a read-only file system by specification.
>
> This breaks Cabal on SmartOS since `/usr` is read-only by design and Cabal calls `getPermissions "/usr/bin/ld"`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------- |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | libraries/directory |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"`System.Directory.getPermissions` fails on read-only filesystem","status":"New","operating_system":"","component":"libraries/directory","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Alain O'Dea reports in an [http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/21078 email] that:\r\n\r\n{{{\r\nPrelude> System.Directory.getPermissions \"/usr/bin/ld\"\r\n*** Exception: /usr/bin/ld: fileAccess: permission denied (Read-only file system)\r\n}}}\r\n> That seems wrong.\r\n>\r\n> An `access(*, W_OK)` syscall by design should return `EROFS` on a read-only file system by specification.\r\n>\r\n> This breaks Cabal on SmartOS since `/usr` is read-only by design and Cabal calls `getPermissions \"/usr/bin/ld\"`.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1AlainODeaAlainODeahttps://gitlab.haskell.org/ghc/ghc/-/issues/87347.8.1 rc1 ghci won't load compiled files2019-07-07T18:43:44Zgeorge.colpitts7.8.1 rc1 ghci won't load compiled files<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.1-rc1 |
| Type | Bug |
| TypeOfFailure |...<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.1-rc1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"7.8.1 rc1 ghci won't load compiled files","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"7.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.1-rc1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["hvr"],"type":"Bug","description":"","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/7787modifyMVar does not restore value if callback returns error value2019-07-07T18:48:09ZjoeyadamsmodifyMVar does not restore value if callback returns error value`modifyMVar` is currently implemented as follows:
```
modifyMVar :: MVar a -> (a -> IO (a,b)) -> IO b
modifyMVar m io =
mask $ \restore -> do
a <- takeMVar m
(a',b) <- restore (io a) `onException` putMVar m a
putMVar ...`modifyMVar` is currently implemented as follows:
```
modifyMVar :: MVar a -> (a -> IO (a,b)) -> IO b
modifyMVar m io =
mask $ \restore -> do
a <- takeMVar m
(a',b) <- restore (io a) `onException` putMVar m a
putMVar m a'
return b
```
The problem is that it forces the `(a',b)` outside of the exception handler. If forcing this throws an exception, `putMVar` will not be called, and a subsequent `withMVar` or similar will hang. Example:
```
> import Control.Concurrent.MVar
> mv <- newMVar 'x'
> modifyMVar mv $ \_ -> return undefined
*** Exception: Prelude.undefined
> withMVar mv print
-- hang --
```
Perhaps we can fix it like this:
```
- (a',b) <- restore (io a) `onException` putMVar m a
+ (a',b) <- restore (io a >>= evaluate) `onException` putMVar m a
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.7 |
| 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":"modifyMVar does not restore value if callback returns error value","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`modifyMVar` is currently implemented as follows:\r\n\r\n{{{\r\nmodifyMVar :: MVar a -> (a -> IO (a,b)) -> IO b\r\nmodifyMVar m io =\r\n mask $ \\restore -> do\r\n a <- takeMVar m\r\n (a',b) <- restore (io a) `onException` putMVar m a\r\n putMVar m a'\r\n return b\r\n}}}\r\n\r\nThe problem is that it forces the `(a',b)` outside of the exception handler. If forcing this throws an exception, `putMVar` will not be called, and a subsequent `withMVar` or similar will hang. Example:\r\n\r\n{{{\r\n> import Control.Concurrent.MVar\r\n> mv <- newMVar 'x'\r\n> modifyMVar mv $ \\_ -> return undefined\r\n*** Exception: Prelude.undefined\r\n> withMVar mv print\r\n-- hang --\r\n}}}\r\n\r\nPerhaps we can fix it like this:\r\n\r\n{{{\r\n- (a',b) <- restore (io a) `onException` putMVar m a\r\n+ (a',b) <- restore (io a >>= evaluate) `onException` putMVar m a\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/8952Bang patterns don't work as the specification says2019-07-07T18:42:39ZdolioBang patterns don't work as the specification saysIn investigating the behavior of bang patterns for an implementation of my own, I came across a discrepancy between the specification and GHC's implementation. Here is an example:
```
case Nothing of
!(~(Just x)) -> 5
Nothing -...In investigating the behavior of bang patterns for an implementation of my own, I came across a discrepancy between the specification and GHC's implementation. Here is an example:
```
case Nothing of
!(~(Just x)) -> 5
Nothing -> 12
```
This evaluates to 12. In other words, !(\~p) is equivalent to p. However, the bang patterns description says that this should be equivalent to:
```
Nothing `seq` case Nothing of
~(Just x) -> 5
Nothing -> 12
```
which evaluates to 5. So, one of either the description or the implementation must be incorrect. In fact, GHC is even a bit confused, as it issues a warning about overlapping patterns for the bang pattern case statement, even though the successful branch is the 'unreachable' one.
The description makes more sense to me, but I'm not terribly invested in the behavior of this; it is admittedly a pretty obscure corner case.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.6.3 |
| 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":"Bang patterns don't work as the specification says","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"In investigating the behavior of bang patterns for an implementation of my own, I came across a discrepancy between the specification and GHC's implementation. Here is an example:\r\n\r\n{{{\r\ncase Nothing of\r\n !(~(Just x)) -> 5\r\n Nothing -> 12\r\n}}}\r\n\r\nThis evaluates to 12. In other words, !(~p) is equivalent to p. However, the bang patterns description says that this should be equivalent to:\r\n\r\n{{{\r\nNothing `seq` case Nothing of\r\n ~(Just x) -> 5\r\n Nothing -> 12\r\n}}}\r\n\r\nwhich evaluates to 5. So, one of either the description or the implementation must be incorrect. In fact, GHC is even a bit confused, as it issues a warning about overlapping patterns for the bang pattern case statement, even though the successful branch is the 'unreachable' one.\r\n\r\nThe description makes more sense to me, but I'm not terribly invested in the behavior of this; it is admittedly a pretty obscure corner case.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/8433forkProcess masks async exceptions inside the child process2019-07-07T18:45:05ZjoeyhforkProcess masks async exceptions inside the child processFrankly, I'm not sure if this is a bug, but the forkProcess documentation says nothing about it. This can lead to problems when writing a multi-threaded daemon that expects async exceptions to work as they usually would.
FWIW, I have lo...Frankly, I'm not sure if this is a bug, but the forkProcess documentation says nothing about it. This can lead to problems when writing a multi-threaded daemon that expects async exceptions to work as they usually would.
FWIW, I have looked at several of the libraries on hackage that handle daemonization, and none of them seem to deal with this by explicitly unmasking exceptions when running the daemon IO action.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.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":"forkProcess masks async exceptions inside the child process","status":"New","operating_system":"","component":"libraries/unix","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Frankly, I'm not sure if this is a bug, but the forkProcess documentation says nothing about it. This can lead to problems when writing a multi-threaded daemon that expects async exceptions to work as they usually would.\r\n\r\nFWIW, I have looked at several of the libraries on hackage that handle daemonization, and none of them seem to deal with this by explicitly unmasking exceptions when running the daemon IO action.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/7815STM fails to validate read.2020-01-29T16:18:56ZRyan YatesSTM fails to validate read.This issue was brought up by napping in `#haskell` with this paste:
[http://hpaste.org/85134](http://hpaste.org/85134) (the first paste in particular)
The code is:
```
import Control.Concurrent.STM
import Control.Concurrent
import Con...This issue was brought up by napping in `#haskell` with this paste:
[http://hpaste.org/85134](http://hpaste.org/85134) (the first paste in particular)
The code is:
```
import Control.Concurrent.STM
import Control.Concurrent
import Control.Monad
main = do
dog <- newTVarIO False
cat <- newTVarIO False
let unset = do
d <- readTVar dog
c <- readTVar cat
if (d || c) then retry else return ()
setDog = unset >> writeTVar dog True
setCat = unset >> writeTVar cat True
oops = do
d <- readTVar dog
c <- readTVar cat
guard (d && c)
reset = do
writeTVar dog False
writeTVar cat False
reset' = do
d <- readTVar dog
c <- readTVar cat
guard (d || c)
reset
forkIO (atomically oops >> putStrLn "Oh Noes!")
forever (do
forkIO (atomically setDog)
forkIO (atomically setCat)
atomically reset'
atomically reset')
```
When run it produces:
```
$ ghc --make test.hs -threaded -rtsopts
$ ./test +RTS -N2
Oh Noes!
test: thread blocked indefinitely in an STM transaction
```
The second message is just a consequence of entering an unexpected state. The first message indicates that both the transactions `cat` and `dog` committed at the same time.
It does this for HEAD and 7.6.
I've sketched out an interleaving that leads to this. TRec entries
are in the first and third column and TVar's are in the second column. Each entry has a TVar name and the expected value followed
by the new value and then a number of updates if it has been read. TVars list their value and their number of updates.
```
A TRec TVar B TRec
-- Transactions start
cat F F cat F 0 cat F F -- Initial reads.
dog F F dog F 0 dog F F
cat F T dog F T -- Local writes in TRec's
-- Validation:
cat F F 0 -- B reads num_updates from cat (with
^ -- consistency check with value)
cat F T cat A 0 | -- A acquires lock for cat (atomic cas)
dog F F 0 ^ | -- A reads num_updates from dog (with
^ | | -- consistency check with value)
| dog B 0 dog F T | -- B acquires lock for dog (atomic cas)
| | ^ |
| | | |
Success 0 | 0 | -- read check for A
Success 0 0 -- read check for B
cat A 1 -- Increment version
cat T 1 -- Unlock with new value
dog B 1 -- Increment version
dog B T -- Unlock with new value
```
What is clear here is that the version number is not enough to check
in `check_read_only` because there is a gap between locking and
incrementing the version. We need to know atomically that the TVar is not locked and it's version number is the same.
I need to read through the right parts of Keir Fraser's thesis carefully, but it seems like the read phase here is only helpful in preventing a commit that writes back the exact value we have already seen while we are in the middle of committing.
The code for `check_read_only` is here:
```c
static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) {
StgBool result = TRUE;
ASSERT (config_use_read_phase);
IF_STM_FG_LOCKS({
FOR_EACH_ENTRY(trec, e, {
StgTVar *s;
s = e -> tvar;
if (entry_is_read_only(e)) {
TRACE("%p : check_read_only for TVar %p, saw %ld", trec, s, e -> num_updates);
if (s -> num_updates != e -> num_updates) {
// ||s -> current_value != e -> expected_value) {
TRACE("%p : mismatch", trec);
result = FALSE;
BREAK_FOR_EACH;
}
}
});
});
return result;
}
```
If I restore the commented out line (which appears commented out in the first commit of this code that I can find) I can't reproduce the issue, but I think there is still a problem due to the ordering of
those checks: we could observe the version as the same, while it
is locked, have the TVar unlock, then observe the value the same.
Switching the order we can only observe the TVar unlocked if the
update has been incremented (as long as we are on an architecture
that ensures this such as x86).
Does this seem right? One issue is that given the interleaving that above with this added check *both* transactions could fail to commit. I think the algorithms from Fraser avoid this, but I think it always involves invalidating another transaction (i.e. killing off any other transactions observed to be in the read check phase with an overlapping TVar in a way that results in only one winner (see page 21 section 4.4 in *Concurrent Programming Without Locks*)).
As a side note, the issue can be avoided by ensuring that the reads become writes and avoiding the read only check. But you can only
become a write if the values do not have matching pointers, switching to Ints instead of Bools gets you there.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.7 |
| 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":"STM fails to validate read.","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":["STM"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This issue was brought up by napping in {{{#haskell}}} with this paste:\r\n\r\n[http://hpaste.org/85134] (the first paste in particular)\r\n\r\nThe code is:\r\n\r\n{{{\r\nimport Control.Concurrent.STM\r\nimport Control.Concurrent\r\nimport Control.Monad\r\n\r\nmain = do\r\n dog <- newTVarIO False\r\n cat <- newTVarIO False\r\n let unset = do\r\n d <- readTVar dog\r\n c <- readTVar cat\r\n if (d || c) then retry else return ()\r\n setDog = unset >> writeTVar dog True\r\n setCat = unset >> writeTVar cat True\r\n oops = do\r\n d <- readTVar dog\r\n c <- readTVar cat\r\n guard (d && c)\r\n reset = do\r\n writeTVar dog False\r\n writeTVar cat False\r\n reset' = do\r\n d <- readTVar dog\r\n c <- readTVar cat\r\n guard (d || c)\r\n reset\r\n\r\n forkIO (atomically oops >> putStrLn \"Oh Noes!\")\r\n forever (do\r\n forkIO (atomically setDog)\r\n forkIO (atomically setCat)\r\n atomically reset'\r\n atomically reset')\r\n}}}\r\n\r\nWhen run it produces:\r\n\r\n{{{\r\n$ ghc --make test.hs -threaded -rtsopts\r\n$ ./test +RTS -N2\r\nOh Noes!\r\ntest: thread blocked indefinitely in an STM transaction\r\n}}}\r\n\r\nThe second message is just a consequence of entering an unexpected state. The first message indicates that both the transactions {{{cat}}} and {{{dog}}} committed at the same time.\r\n\r\nIt does this for HEAD and 7.6.\r\n\r\nI've sketched out an interleaving that leads to this. TRec entries\r\nare in the first and third column and TVar's are in the second column. Each entry has a TVar name and the expected value followed\r\nby the new value and then a number of updates if it has been read. TVars list their value and their number of updates.\r\n\r\n{{{\r\n A TRec TVar B TRec\r\n -- Transactions start\r\ncat F F cat F 0 cat F F -- Initial reads.\r\ndog F F dog F 0 dog F F \r\n\r\ncat F T dog F T -- Local writes in TRec's\r\n \r\n -- Validation:\r\n\r\n cat F F 0 -- B reads num_updates from cat (with\r\n ^ -- consistency check with value)\r\ncat F T cat A 0 | -- A acquires lock for cat (atomic cas)\r\ndog F F 0 ^ | -- A reads num_updates from dog (with\r\n ^ | | -- consistency check with value)\r\n | dog B 0 dog F T | -- B acquires lock for dog (atomic cas)\r\n | | ^ | \r\n | | | |\r\nSuccess 0 | 0 | -- read check for A\r\nSuccess 0 0 -- read check for B\r\n\r\n cat A 1 -- Increment version\r\n cat T 1 -- Unlock with new value\r\n dog B 1 -- Increment version\r\n dog B T -- Unlock with new value\r\n}}}\r\n\r\nWhat is clear here is that the version number is not enough to check\r\nin {{{check_read_only}}} because there is a gap between locking and \r\nincrementing the version. We need to know atomically that the TVar is not locked and it's version number is the same.\r\n\r\nI need to read through the right parts of Keir Fraser's thesis carefully, but it seems like the read phase here is only helpful in preventing a commit that writes back the exact value we have already seen while we are in the middle of committing. \r\n\r\nThe code for {{{check_read_only}}} is here:\r\n\r\n{{{\r\n#!c\r\nstatic StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) {\r\n StgBool result = TRUE;\r\n\r\n ASSERT (config_use_read_phase);\r\n IF_STM_FG_LOCKS({\r\n FOR_EACH_ENTRY(trec, e, {\r\n StgTVar *s;\r\n s = e -> tvar;\r\n if (entry_is_read_only(e)) {\r\n TRACE(\"%p : check_read_only for TVar %p, saw %ld\", trec, s, e -> num_updates);\r\n if (s -> num_updates != e -> num_updates) {\r\n // ||s -> current_value != e -> expected_value) {\r\n TRACE(\"%p : mismatch\", trec);\r\n result = FALSE;\r\n BREAK_FOR_EACH;\r\n }\r\n }\r\n });\r\n });\r\n\r\n return result;\r\n}\r\n}}}\r\n\r\nIf I restore the commented out line (which appears commented out in the first commit of this code that I can find) I can't reproduce the issue, but I think there is still a problem due to the ordering of\r\nthose checks: we could observe the version as the same, while it \r\nis locked, have the TVar unlock, then observe the value the same. \r\n\r\nSwitching the order we can only observe the TVar unlocked if the\r\nupdate has been incremented (as long as we are on an architecture\r\nthat ensures this such as x86).\r\n\r\nDoes this seem right? One issue is that given the interleaving that above with this added check ''both'' transactions could fail to commit. I think the algorithms from Fraser avoid this, but I think it always involves invalidating another transaction (i.e. killing off any other transactions observed to be in the read check phase with an overlapping TVar in a way that results in only one winner (see page 21 section 4.4 in ''Concurrent Programming Without Locks'')).\r\n\r\nAs a side note, the issue can be avoided by ensuring that the reads become writes and avoiding the read only check. But you can only \r\nbecome a write if the values do not have matching pointers, switching to Ints instead of Bools gets you there.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Ian Lynagh <igloo@earth.li>Ian Lynagh <igloo@earth.li>https://gitlab.haskell.org/ghc/ghc/-/issues/7773Waiting on non-kqueue supported files on OS X2019-07-07T18:48:12ZAndreasVoellmyWaiting on non-kqueue supported files on OS XNeither the old IO manager nor the new "parallel" IO manager properly handle waiting on files on Mac OS X when kqueue does not support the device type. PHO reported this on ghc-devs: http://www.haskell.org/pipermail/ghc-devs/2013-March/0...Neither the old IO manager nor the new "parallel" IO manager properly handle waiting on files on Mac OS X when kqueue does not support the device type. PHO reported this on ghc-devs: http://www.haskell.org/pipermail/ghc-devs/2013-March/000798.html.
Here is the gist of it: the IO manager uses kqueue to wait on files on OS X. kqueue does not support all files. For example, on older versions of OS X (10.5.8) it cannot wait on tty devices and on even on 10.8.2 it cannot wait on /dev/random.
Both the old and parallel IO managers suffered from the problem, but the consequences were slightly different. With the old IO manager the situation was treated as the file being ready, which would just cause the waiting thread to run again. The parallel IO manager changed things slightly and now it just throws an exception and terminates the program. So the behavior when this happens in the parallel IO manager is not acceptable.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.7 |
| 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":"Waiting on non-kqueue supported files on OS X","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Neither the old IO manager nor the new \"parallel\" IO manager properly handle waiting on files on Mac OS X when kqueue does not support the device type. PHO reported this on ghc-devs: http://www.haskell.org/pipermail/ghc-devs/2013-March/000798.html.\r\n\r\nHere is the gist of it: the IO manager uses kqueue to wait on files on OS X. kqueue does not support all files. For example, on older versions of OS X (10.5.8) it cannot wait on tty devices and on even on 10.8.2 it cannot wait on /dev/random. \r\n\r\nBoth the old and parallel IO managers suffered from the problem, but the consequences were slightly different. With the old IO manager the situation was treated as the file being ready, which would just cause the waiting thread to run again. The parallel IO manager changed things slightly and now it just throws an exception and terminates the program. So the behavior when this happens in the parallel IO manager is not acceptable.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1AndreasVoellmyAndreasVoellmyhttps://gitlab.haskell.org/ghc/ghc/-/issues/7491getNumCapabilities uses n_capabilities instead of enabled_capabilities2019-07-07T18:49:31ZYurasgetNumCapabilities uses n_capabilities instead of enabled_capabilitiessetNumCapabilities newer removes capabilities, it just disables them when new value is less the the current one. In that case getNumCapabilities returns wrong result.
<details><summary>Trac metadata</summary>
| Trac field |...setNumCapabilities newer removes capabilities, it just disables them when new value is less the the current one. In that case getNumCapabilities returns wrong result.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------------- |
| Version | 7.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | shumovichy@gmail.com |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"getNumCapabilities uses n_capabilities instead of enabled_capabilities","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["shumovichy@gmail.com"],"type":"Bug","description":"setNumCapabilities newer removes capabilities, it just disables them when new value is less the the current one. In that case getNumCapabilities returns wrong result.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/7399Test Posix004 fails in test-suite2019-07-07T18:49:54ZpaulhTest Posix004 fails in test-suiteAfter a standard build of ghc-7.6.1 on debian wheezy, the test-suite fails on the test posix004.
The error given is:
```
Wrong exit code (expected 0 , actual 1 )
Stdout:
Stderr:
posix004: unexpected termination cause
*** unexpected f...After a standard build of ghc-7.6.1 on debian wheezy, the test-suite fails on the test posix004.
The error given is:
```
Wrong exit code (expected 0 , actual 1 )
Stdout:
Stderr:
posix004: unexpected termination cause
*** unexpected failure for posix004(normal)
```7.8.1Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/7139GHCi is too verbose on -v02019-07-07T18:51:09ZSimon Hengelsol@typeful.netGHCi is too verbose on -v0Steps to reproduce:
```
sol@x200:~$ ghci -v0
Prelude> :set -packageghc
```
I'd expect that nothing is printed, but the following is printed instead:
```
package flags have changed, resetting and loading new packages...
```
Currently ...Steps to reproduce:
```
sol@x200:~$ ghci -v0
Prelude> :set -packageghc
```
I'd expect that nothing is printed, but the following is printed instead:
```
package flags have changed, resetting and loading new packages...
```
Currently this is not really an issue for me. I stumbled upon it while investigating #7138.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.4.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHCi is too verbose on -v0","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Steps to reproduce:\r\n\r\n{{{\r\nsol@x200:~$ ghci -v0\r\nPrelude> :set -packageghc\r\n}}}\r\n\r\nI'd expect that nothing is printed, but the following is printed instead:\r\n{{{\r\npackage flags have changed, resetting and loading new packages...\r\n}}}\r\n\r\nCurrently this is not really an issue for me. I stumbled upon it while investigating #7138.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1pcapriottipcapriottihttps://gitlab.haskell.org/ghc/ghc/-/issues/6117Cyclic Type Class Hierarchy Produces <<loop>>2019-07-07T18:52:05Zjun0Cyclic Type Class Hierarchy Produces <<loop>>If there is a cyclic class hierarchy like
```
class B a => Semigroup a where ...[[BR]]
class Semigroup (Additive a) => Ring a where ...[[BR]]
instance Ring a => Semigroup (Additive a) where ...[[BR]]
```
...If there is a cyclic class hierarchy like
```
class B a => Semigroup a where ...[[BR]]
class Semigroup (Additive a) => Ring a where ...[[BR]]
instance Ring a => Semigroup (Additive a) where ...[[BR]]
```
then uses of B's methods on `(Additive a)` in the method implementations of the
third declaration `instance Ring a => Semigroup (Additive a)` will:
1. be accepted by the compiler even in cases where `B (Additive a)` is not derivable.
1. result in \<\<loop\>\>.
The attached program prints \<\<loop\>\> when compiled with GHC-7.2.1 or newer but prints 1234567890 when compiled with GHC-7.0.4 or older. I haven't had time to try out any revisions in between those two, but I did check that HEAD produces \<\<loop\>\> as well.7.8.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/6026Unboxed operators have wrong fixity2019-07-07T18:52:31ZbenlUnboxed operators have wrong fixity```
$ ghci -XMagicHash
$ :m GHC.Exts
> 1 + 2 * 3
7
> I# (1# +# 2# *# 3#)
9
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version |...```
$ ghci -XMagicHash
$ :m GHC.Exts
> 1 + 2 * 3
7
> I# (1# +# 2# *# 3#)
9
```
<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":"Unboxed operators have wrong fixity","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":"{{{\r\n$ ghci -XMagicHash\r\n$ :m GHC.Exts\r\n> 1 + 2 * 3\r\n7\r\n> I# (1# +# 2# *# 3#)\r\n9\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Ian Lynagh <igloo@earth.li>Ian Lynagh <igloo@earth.li>https://gitlab.haskell.org/ghc/ghc/-/issues/5070dph and new code generator don't play nicely with each other2019-07-07T18:57:01ZEdward Z. Yangdph and new code generator don't play nicely with each otherI'm looking at the current failure of DPH with the new code generator,
which is a bit different from what I've dealt with before. The bug appears
to be in the compiled libraries code, and I can tickle it with the
following minimized exam...I'm looking at the current failure of DPH with the new code generator,
which is a bit different from what I've dealt with before. The bug appears
to be in the compiled libraries code, and I can tickle it with the
following minimized example:
```
{-# LANGUAGE ParallelArrays #-}
{-# OPTIONS -fvectorise #-}
module PrimesVect where
import Data.Array.Parallel.Prelude
import qualified Prelude
f :: PArray Bool
f = toPArrayP f'
f' :: [:Bool:]
f' = [: True | _ <- singletonP True, g emptyP:]
g :: [:Bool:] -> Bool
g ps = andP [: True | _ <- ps:]
```
and a runner:
```
import qualified Data.Array.Parallel.PArray as P
import PrimesVect
main = print (P.toList f)
```
I expect to get \[True\], but instead I get:
```
dph-primespj-fast: libraries/vector/Data/Vector/Generic.hs:369 (slice): invalid slice (0,1,0)
dph-primespj-fast: thread blocked indefinitely in an MVar operation
```
Now, in the situation that the library code is broken, I'd usually try to inline
all of the library code and then pare that down into something manageable. Unfortunately,
DPH is pretty closely tied to the compiler, so I don't see an easy way to do that.
So I'm not really sure how to go about debugging this.
Note that we can't work on this bug until #5065 is resolved, since these tests are currently failing for unrelated reasons.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.0.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Data Parallel Haskell |
| Test case | |
| Differential revisions | |
| BlockedBy | #5065 |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[5065],"summary":"dph and new code generator don't play nicely with each other","status":"New","operating_system":"","component":"Data Parallel Haskell","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm looking at the current failure of DPH with the new code generator,\r\nwhich is a bit different from what I've dealt with before. The bug appears\r\nto be in the compiled libraries code, and I can tickle it with the\r\nfollowing minimized example:\r\n\r\n{{{\r\n {-# LANGUAGE ParallelArrays #-}\r\n {-# OPTIONS -fvectorise #-}\r\n module PrimesVect where\r\n\r\n import Data.Array.Parallel.Prelude\r\n import qualified Prelude \r\n \r\n f :: PArray Bool \r\n f = toPArrayP f'\r\n\r\n f' :: [:Bool:]\r\n f' = [: True | _ <- singletonP True, g emptyP:]\r\n\r\n g :: [:Bool:] -> Bool\r\n g ps = andP [: True | _ <- ps:]\r\n}}}\r\n\r\nand a runner:\r\n\r\n{{{\r\n import qualified Data.Array.Parallel.PArray as P\r\n import PrimesVect\r\n\r\n main = print (P.toList f)\r\n}}}\r\n\r\nI expect to get [True], but instead I get:\r\n\r\n{{{\r\n dph-primespj-fast: libraries/vector/Data/Vector/Generic.hs:369 (slice): invalid slice (0,1,0)\r\n dph-primespj-fast: thread blocked indefinitely in an MVar operation\r\n}}}\r\n\r\nNow, in the situation that the library code is broken, I'd usually try to inline\r\nall of the library code and then pare that down into something manageable. Unfortunately,\r\nDPH is pretty closely tied to the compiler, so I don't see an easy way to do that.\r\nSo I'm not really sure how to go about debugging this.\r\n\r\nNote that we can't work on this bug until #5065 is resolved, since these tests are currently failing for unrelated reasons.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1benlbenlhttps://gitlab.haskell.org/ghc/ghc/-/issues/8849Unregisterised compiler: arithmetic failure2019-07-07T18:43:07ZPeter Trommlerptrommler@acm.orgUnregisterised compiler: arithmetic failureCompiling the following with RC2 on powerpc 64 downloaded from haskell.org:
```
main = putStr $ show (-1.0000000001 :: Double)
```
Setting `-O` yields:
```
0.0
```
Without optimization the correct result is displayed.
I prepared an ...Compiling the following with RC2 on powerpc 64 downloaded from haskell.org:
```
main = putStr $ show (-1.0000000001 :: Double)
```
Setting `-O` yields:
```
0.0
```
Without optimization the correct result is displayed.
I prepared an unregisterised compiler on amd64 and see the same issue and more arithmetic tests fail in testsuite. In fact I took the above from arith005.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 7.8.1-rc2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Unregisterised compiler: arithmetic failure","status":"New","operating_system":"Unknown/Multiple","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.1-rc2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Compiling the following with RC2 on powerpc 64 downloaded from haskell.org:\r\n{{{\r\nmain = putStr $ show (-1.0000000001 :: Double)\r\n}}}\r\nSetting {{{-O}}} yields:\r\n{{{\r\n0.0\r\n}}}\r\nWithout optimization the correct result is displayed.\r\n\r\nI prepared an unregisterised compiler on amd64 and see the same issue and more arithmetic tests fail in testsuite. In fact I took the above from arith005.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.4https://gitlab.haskell.org/ghc/ghc/-/issues/9860Package flags not command line completable in 7.82019-07-07T18:38:44Zkolmodin@dtek.chalmers.sePackage flags not command line completable in 7.8Passing `--show-options` to ghc shows all the flags that ghc understands.
Unfortunately `--show-options` does not list the package flags, `-package-db -package-id` etc.
Requires a 1 line fix in `ghc/Main.hs`.
<details><summary>Trac me...Passing `--show-options` to ghc shows all the flags that ghc understands.
Unfortunately `--show-options` does not list the package flags, `-package-db -package-id` etc.
Requires a 1 line fix in `ghc/Main.hs`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| 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":"Package flags not command line completable in 7.8","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"7.8.4","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Passing `--show-options` to ghc shows all the flags that ghc understands.\r\n\r\nUnfortunately `--show-options` does not list the package flags, `-package-db -package-id` etc.\r\n\r\nRequires a 1 line fix in `ghc/Main.hs`.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.4kolmodin@dtek.chalmers.sekolmodin@dtek.chalmers.sehttps://gitlab.haskell.org/ghc/ghc/-/issues/9817signal handlers in unix are passed garbage when using the signle threaded rts2023-09-09T22:39:58Zrednebsignal handlers in unix are passed garbage when using the signle threaded rtsWhen a signal handler (registered with `GHC.Conc.Signal.setHandler`) is called upon the receipt of the relevant signal, it is passed a memory buffer in the form of a `ForeignPtr Word8`. This buffer contains a copy of the `siginfo_t` stru...When a signal handler (registered with `GHC.Conc.Signal.setHandler`) is called upon the receipt of the relevant signal, it is passed a memory buffer in the form of a `ForeignPtr Word8`. This buffer contains a copy of the `siginfo_t` struct that was originally passed to the underlying os signal handler. Unfortunately, this only seems to work correctly in the threaded rts. In the single-threaded rts, the buffer contains garbage. This can be demonstrated by the following program:
```hs
import Control.Concurrent
import System.Posix.Signals
main :: IO ()
main = do
wait <- newEmptyMVar
_ <- flip (installHandler sig) Nothing $ CatchInfo $ \info -> do
putStrLn $ "Received a signal " ++ show (siginfoSignal info)
putMVar wait ()
raiseSignal sig
putStrLn $ "Sending myself a signal " ++ show sig
takeMVar wait
where
sig = sigUSR2
```
If you compile the program with the `-threaded` flag then everything works just fine:
```
Sending myself a signal 12
Received a signal 12
```
but without it, the signal handler will print a totaly random signal number:
```
Sending myself a signal 12
Received a signal 138644296
```
I was able to track this down to the function `startSignalHandlers` in `rts/posix/Signals.c`. This function (which is only used by the single threaded rts) allocates a buffer and copies the `siginfo_t` struct to it and then schedules `GHC.Conc.Signal.runHandlers` to be run in a new thread. The problem is that while `GHC.Conc.Signal.runHandlers` expects a `ForeignPtr Word8`, here it is given a `Ptr Word8`. This has two implications: the signal handler is given invalid data, and nobody is deallocating the buffer so we are leaking memory every time a signal is received that has a custom handler.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"signal handlers in unix are passed garbage when using the signle threaded rts","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"When a signal handler (registered with `GHC.Conc.Signal.setHandler`) is called upon the receipt of the relevant signal, it is passed a memory buffer in the form of a `ForeignPtr Word8`. This buffer contains a copy of the `siginfo_t` struct that was originally passed to the underlying os signal handler. Unfortunately, this only seems to work correctly in the threaded rts. In the single-threaded rts, the buffer contains garbage. This can be demonstrated by the following program:\r\n\r\n{{{#!hs\r\nimport Control.Concurrent\r\nimport System.Posix.Signals\r\n\r\nmain :: IO ()\r\nmain = do\r\n wait <- newEmptyMVar\r\n _ <- flip (installHandler sig) Nothing $ CatchInfo $ \\info -> do\r\n putStrLn $ \"Received a signal \" ++ show (siginfoSignal info)\r\n putMVar wait ()\r\n raiseSignal sig\r\n putStrLn $ \"Sending myself a signal \" ++ show sig\r\n takeMVar wait\r\n where\r\n sig = sigUSR2\r\n}}}\r\n\r\nIf you compile the program with the `-threaded` flag then everything works just fine:\r\n{{{\r\nSending myself a signal 12\r\nReceived a signal 12\r\n}}}\r\nbut without it, the signal handler will print a totaly random signal number:\r\n{{{\r\nSending myself a signal 12\r\nReceived a signal 138644296\r\n}}}\r\n\r\nI was able to track this down to the function `startSignalHandlers` in `rts/posix/Signals.c`. This function (which is only used by the single threaded rts) allocates a buffer and copies the `siginfo_t` struct to it and then schedules `GHC.Conc.Signal.runHandlers` to be run in a new thread. The problem is that while `GHC.Conc.Signal.runHandlers` expects a `ForeignPtr Word8`, here it is given a `Ptr Word8`. This has two implications: the signal handler is given invalid data, and nobody is deallocating the buffer so we are leaking memory every time a signal is received that has a custom handler.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.4Simon MarlowSimon Marlow