GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2020-07-27T06:51:33Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/10956Allow default keyboard behavior to be easily overriden2020-07-27T06:51:33ZBalinKingOfMoriaAllow default keyboard behavior to be easily overridenIf I press the up or down arrow keys, GHC kicks in and makes it so that the last line of text comes back instead of letting me intercept the arrow key. From what I have seen, you need third-party libraries to override the default behavio...If I press the up or down arrow keys, GHC kicks in and makes it so that the last line of text comes back instead of letting me intercept the arrow key. From what I have seen, you need third-party libraries to override the default behavior, but when would a user actually want that behavior in an application instead of letting the programmer handle it? Can there be a switch (like a special LANGUAGE pragma or whatever) to enable raw input capture?
Console text editing applications are greatly hindered by this automatic behavior.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.3 |
| Type | FeatureRequest |
| 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":"Allow default keyboard behavior to be easily overriden","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["input","io","raw"],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"FeatureRequest","description":"If I press the up or down arrow keys, GHC kicks in and makes it so that the last line of text comes back instead of letting me intercept the arrow key. From what I have seen, you need third-party libraries to override the default behavior, but when would a user actually want that behavior in an application instead of letting the programmer handle it? Can there be a switch (like a special LANGUAGE pragma or whatever) to enable raw input capture?\r\nConsole text editing applications are greatly hindered by this automatic behavior.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/5797readRawBufferPtr cannot be interrupted by exception on Windows with -threaded2020-07-27T06:44:05ZjoeyadamsreadRawBufferPtr cannot be interrupted by exception on Windows with -threadedOn Windows, in a program compiled with -threaded, if a thread receives from a Handle created by the network package (e.g. with hGetLine), it cannot be interrupted by an asynchronous exception.
I've traced it down to readRawBufferPtr, wh...On Windows, in a program compiled with -threaded, if a thread receives from a Handle created by the network package (e.g. with hGetLine), it cannot be interrupted by an asynchronous exception.
I've traced it down to readRawBufferPtr, which is used by Network.Socket.recv. Although I haven't tested readRawBufferPtr directly, my test case (attached) tests Network.Socket.recv.
For Windows, base 4.4.1.0 implements it as:
```
readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
readRawBufferPtr loc !fd buf off len
| threaded = blockingReadRawBufferPtr loc fd buf off len
| otherwise = asyncReadRawBufferPtr loc fd buf off len
...
blockingReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
blockingReadRawBufferPtr loc fd buf off len
= fmap fromIntegral $ throwErrnoIfMinus1Retry loc $
if fdIsSocket fd
then c_safe_recv (fdFD fd) (buf `plusPtr` off) len 0
else c_safe_read (fdFD fd) (buf `plusPtr` off) len
...
-- NOTE: "safe" versions of the read/write calls for use by the threaded RTS.
-- These calls may block, but that's ok.
foreign import stdcall safe "recv"
c_safe_recv :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize
foreign import stdcall safe "send"
c_safe_send :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize
```
If I understand correctly, safe foreign calls cannot be interrupted by asynchronous exceptions.
Is this a bug in readRawBufferPtr, or a bug in the network package? Can a caller expect readRawBufferPtr to be interruptible by an exception?
<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":"readRawBufferPtr cannot be interrupted by exception on Windows with -threaded","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":"On Windows, in a program compiled with -threaded, if a thread receives from a Handle created by the network package (e.g. with hGetLine), it cannot be interrupted by an asynchronous exception.\r\n\r\nI've traced it down to readRawBufferPtr, which is used by Network.Socket.recv. Although I haven't tested readRawBufferPtr directly, my test case (attached) tests Network.Socket.recv.\r\n\r\nFor Windows, base 4.4.1.0 implements it as:\r\n\r\n{{{\r\nreadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt\r\nreadRawBufferPtr loc !fd buf off len\r\n | threaded = blockingReadRawBufferPtr loc fd buf off len\r\n | otherwise = asyncReadRawBufferPtr loc fd buf off len\r\n\r\n...\r\n\r\nblockingReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt\r\nblockingReadRawBufferPtr loc fd buf off len\r\n = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $\r\n if fdIsSocket fd\r\n then c_safe_recv (fdFD fd) (buf `plusPtr` off) len 0\r\n else c_safe_read (fdFD fd) (buf `plusPtr` off) len\r\n\r\n...\r\n\r\n-- NOTE: \"safe\" versions of the read/write calls for use by the threaded RTS.\r\n-- These calls may block, but that's ok.\r\n\r\nforeign import stdcall safe \"recv\"\r\n c_safe_recv :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize\r\n\r\nforeign import stdcall safe \"send\"\r\n c_safe_send :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize\r\n}}}\r\n\r\nIf I understand correctly, safe foreign calls cannot be interrupted by asynchronous exceptions.\r\n\r\nIs this a bug in readRawBufferPtr, or a bug in the network package? Can a caller expect readRawBufferPtr to be interruptible by an exception?","type_of_failure":"OtherFailure","blocking":[]} -->Tamar ChristinaTamar Christinahttps://gitlab.haskell.org/ghc/ghc/-/issues/7353Make system IO interruptible on Windows2020-07-27T06:43:08ZjoeyadamsMake system IO interruptible on WindowsCurrently, IO operations (connect, read, etc.) cannot be interrupted on Windows. Additionally, threadWaitRead and threadWaitWrite do not work on Windows (IIRC, they can't tell if the given file descriptor is a socket or not, so they assu...Currently, IO operations (connect, read, etc.) cannot be interrupted on Windows. Additionally, threadWaitRead and threadWaitWrite do not work on Windows (IIRC, they can't tell if the given file descriptor is a socket or not, so they assume it's not).
The reason is that GHC does not have an IO manager for Windows like it does for \*nix. For Windows with -threaded, the network package uses blocking FFI calls, which cannot be interrupted by asynchronous exceptions. Thus, System.Timeout and killThread can't be used to time out and interrupt network IO.
I'm working on a program that needs to run on a Windows XP machine for long periods of time, interacting with a couple intermittent network services. This issue is making things very difficult for me, so I want to get it fixed. I do not need to support thousands of concurrent connections efficiently; I just need my program to run reliably.
What needs to happen for IO to be interruptible on Windows with -threaded ? I'm willing to put in the work, but there's a lot I'd have to learn about windows IO and GHC IO handling. One question to get started: are threadWaitRead/threadWaitWrite even possible to implement on Windows, or might Windows assign overlapping HANDLE numbers to sockets and regular files?
This issue spans both GHC and the network package, but I'd like to collect information about it in one place. Related issues:
- http://trac.haskell.org/network/ticket/2
- https://github.com/haskell/network/issues/36
- http://hackage.haskell.org/trac/ghc/ticket/3937
- http://hackage.haskell.org/trac/ghc/ticket/5797
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.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":"Make system IO interruptible on Windows","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Currently, IO operations (connect, read, etc.) cannot be interrupted on Windows. Additionally, threadWaitRead and threadWaitWrite do not work on Windows (IIRC, they can't tell if the given file descriptor is a socket or not, so they assume it's not).\r\n\r\nThe reason is that GHC does not have an IO manager for Windows like it does for *nix. For Windows with -threaded, the network package uses blocking FFI calls, which cannot be interrupted by asynchronous exceptions. Thus, System.Timeout and killThread can't be used to time out and interrupt network IO.\r\n\r\nI'm working on a program that needs to run on a Windows XP machine for long periods of time, interacting with a couple intermittent network services. This issue is making things very difficult for me, so I want to get it fixed. I do not need to support thousands of concurrent connections efficiently; I just need my program to run reliably.\r\n\r\nWhat needs to happen for IO to be interruptible on Windows with -threaded ? I'm willing to put in the work, but there's a lot I'd have to learn about windows IO and GHC IO handling. One question to get started: are threadWaitRead/threadWaitWrite even possible to implement on Windows, or might Windows assign overlapping HANDLE numbers to sockets and regular files?\r\n\r\nThis issue spans both GHC and the network package, but I'd like to collect information about it in one place. Related issues:\r\n\r\n * http://trac.haskell.org/network/ticket/2\r\n\r\n * https://github.com/haskell/network/issues/36\r\n\r\n * http://hackage.haskell.org/trac/ghc/ticket/3937\r\n\r\n * http://hackage.haskell.org/trac/ghc/ticket/5797","type_of_failure":"OtherFailure","blocking":[]} -->Tamar ChristinaTamar Christinahttps://gitlab.haskell.org/ghc/ghc/-/issues/12869getChar doesn't work on a new Windows build2020-07-27T06:37:37ZDarwin226getChar doesn't work on a new Windows buildLast night I updated my PC to the 14965 Windows insider build. Today I notice that `getLine` no longer terminates (pressing enter just goes to a new line), but I'm suspecting that the root cause it that `getChar` returns `'\NUL'` no math...Last night I updated my PC to the 14965 Windows insider build. Today I notice that `getLine` no longer terminates (pressing enter just goes to a new line), but I'm suspecting that the root cause it that `getChar` returns `'\NUL'` no mather what is input.
I've tried this both GHCi and in a compiled program.
This is only broken if I set my codepage to 65001 (UTF-8). If I set it to something like 850 it works as it should.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.10.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":"getChar doesn't work on a new Windows build","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"Last night I updated my PC to the 14965 Windows insider build. Today I notice that `getLine` no longer terminates (pressing enter just goes to a new line), but I'm suspecting that the root cause it that `getChar` returns `'\\NUL'` no mather what is input.\r\n\r\nI've tried this both GHCi and in a compiled program.\r\n\r\nThis is only broken if I set my codepage to 65001 (UTF-8). If I set it to something like 850 it works as it should.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/16147ghc-pkg deadlocks on macOS2020-07-15T03:07:47Zrvlghc-pkg deadlocks on macOSIf I run this script on macOS, after about 15 minutes, a `ghc-pkg` process will deadlock.
```sh
#!/usr/bin/env bash
out=`pwd`/testing-package-db
rm -rf $out
cabal update
cabal install random
mkdir -p $out
ghc-pkg init $out/package.c...If I run this script on macOS, after about 15 minutes, a `ghc-pkg` process will deadlock.
```sh
#!/usr/bin/env bash
out=`pwd`/testing-package-db
rm -rf $out
cabal update
cabal install random
mkdir -p $out
ghc-pkg init $out/package.conf.d
while true; do
ghc-pkg --package-db $HOME/.ghc/x86_64-darwin-8.6.3/package.conf.d dump | ghc-pkg --force --package-db $out/package.conf.d register -
done
```
Output from `sw_vers`:
```
ProductName: Mac OS X
ProductVersion: 10.12.6
BuildVersion: 16G29
```
This GHC build comes from the latest nixpkgs-18.09. I have also attached a nix file to build test scripts.
We noticed that if we edited the ghc-pkg binary to link with the threaded RTS, then we could not reproduce the deadlock (after running the test script for 24 hours).
Attached is the output from `/usr/bin/sample` for the stuck process, and the `otool -L ghc-pkg` output.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc-pkg deadlocks on macOS","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If I run this script on macOS, after about 15 minutes, a `ghc-pkg` process will deadlock.\r\n\r\n{{{#!sh\r\n#!/usr/bin/env bash\r\n\r\nout=`pwd`/testing-package-db\r\n\r\nrm -rf $out\r\n\r\ncabal update\r\ncabal install random\r\n\r\nmkdir -p $out\r\nghc-pkg init $out/package.conf.d\r\n\r\nwhile true; do\r\n ghc-pkg --package-db $HOME/.ghc/x86_64-darwin-8.6.3/package.conf.d dump | ghc-pkg --force --package-db $out/package.conf.d register -\r\ndone\r\n}}}\r\n\r\nOutput from `sw_vers`:\r\n{{{\r\nProductName: Mac OS X\r\nProductVersion: 10.12.6\r\nBuildVersion: 16G29\r\n}}}\r\n\r\nThis GHC build comes from the latest nixpkgs-18.09. I have also attached a nix file to build test scripts.\r\n\r\nWe noticed that if we edited the ghc-pkg binary to link with the threaded RTS, then we could not reproduce the deadlock (after running the test script for 24 hours).\r\n\r\nAttached is the output from `/usr/bin/sample` for the stuck process, and the `otool -L ghc-pkg` output.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.6.4https://gitlab.haskell.org/ghc/ghc/-/issues/18418withArgs and withProgName permanently modify argv[0]2020-07-14T14:20:26ZAndreas HerrmannwithArgs and withProgName permanently modify argv[0]## Summary
The functions `withArgs` and `withProgName` are meant to temporarily modify the program arguments, either `argv[1]` and upwards or `argv[0]`. However, they both have the side-effect to permanently modify `argv[0]`.
## Steps ...## Summary
The functions `withArgs` and `withProgName` are meant to temporarily modify the program arguments, either `argv[1]` and upwards or `argv[0]`. However, they both have the side-effect to permanently modify `argv[0]`.
## Steps to reproduce
Consider the following example program (full project attached [ghc_arg0.tgz](/uploads/d2515b74bfbbd1567dd334d1fc7db639/ghc_arg0.tgz)
):
```
module Main where
import Arg0 (getArg0)
import System.Environment (withArgs, withProgName)
main :: IO ()
main = do
before <- getArg0
during <- withProgName "manual" getArg0
-- during <- withArgs [] getArg0
after <- getArg0
putStrLn $ "before " ++ before ++ "\nduring " ++ during ++ "\nafter " ++ after
```
Observe the following behavior
```
$ cabal run
before /home/user/ghc_arg0/dist-newstyle/build/x86_64-linux/ghc-8.10.1/ghc-arg0-0.1.0.0/x/ghc-arg0/build/ghc-arg0/ghc-arg0
during manual
after ghc-arg0
```
I.e. the result of `getArg0` is different before and after `withProgName` (same with `withArgs`).
## Expected behavior
`withProgName` and `withArgs` should fully restore `argv[0]`. I.e. the output above should be
```
before /home/user/ghc_arg0/dist-newstyle/build/x86_64-linux/ghc-8.10.1/ghc-arg0-0.1.0.0/x/ghc-arg0/build/ghc-arg0/ghc-arg0
during manual
after /home/user/ghc_arg0/dist-newstyle/build/x86_64-linux/ghc-8.10.1/ghc-arg0-0.1.0.0/x/ghc-arg0/build/ghc-arg0/ghc-arg0
```
## Environment
* GHC version used: 8.10.1
Optional:
* Operating System: Ubuntu 19.10
* System Architecture: x86_64
## Additional context
As pointed out in https://gitlab.haskell.org/ghc/ghc/-/issues/3199 there is no easy access to `argv[0]` in GHC. The attached example uses a slight variation of `getProgName` that doesn't invoke `basename` on the result. Alternatively, there is https://hackage.haskell.org/package/system-argv0-0.1.1.
The motivating use-case is to determine the path by which the program was invoked, see https://github.com/tweag/rules_haskell/pull/1387 for details. Note, this is not necessarily the same as the result of `getExecutablePath` as that one uses `/proc/self/exe` and resolves symbolic links. The issue was caused by a program calling `getProgName` around an optparse-applicative parser to control the program name in error messages generated by optparse-applicative.https://gitlab.haskell.org/ghc/ghc/-/issues/14455PPC64: Wrong output in print0222020-07-10T03:30:27ZPeter Trommlerptrommler@acm.orgPPC64: Wrong output in print022On powerpc64 Linux print022 fails with the following:
```
-test = C 1 32 1.2 1.23 'x' 1 1.2 1.23
+test = C 1 32 0.0 1.23 'x' 1 1.2 1.23
```
Note, the fourth item is 0.0 instead of 1.2. In ticket #11262 the fourth item was still correct...On powerpc64 Linux print022 fails with the following:
```
-test = C 1 32 1.2 1.23 'x' 1 1.2 1.23
+test = C 1 32 0.0 1.23 'x' 1 1.2 1.23
```
Note, the fourth item is 0.0 instead of 1.2. In ticket #11262 the fourth item was still correct.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------------------ |
| Version | 8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | ghci.debugger/scripts/print022 |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"PPC64: Wrong output in print022","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":["big","endian"],"differentials":[],"test_case":"ghci.debugger/scripts/print022","architecture":"","cc":[""],"type":"Bug","description":"On powerpc64 Linux print022 fails with the following:\r\n{{{\r\n-test = C 1 32 1.2 1.23 'x' 1 1.2 1.23\r\n+test = C 1 32 0.0 1.23 'x' 1 1.2 1.23\r\n}}}\r\n\r\nNote, the fourth item is 0.0 instead of 1.2. In ticket #11262 the fourth item was still correct.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15933Wrong size for int for callbacks into Haskell from foreign code2020-06-14T21:08:58ZIlias TsitsimpisWrong size for int for callbacks into Haskell from foreign codeThe following code produces different results on amd64 (64-bit little endian) and s390x (64-bit big endian).
`foo.h:`
```c
typedef void(*hs_callback)(int x);
extern void function_in_c(hs_callback cb);
```
`foo.c:`
```c
#include "foo....The following code produces different results on amd64 (64-bit little endian) and s390x (64-bit big endian).
`foo.h:`
```c
typedef void(*hs_callback)(int x);
extern void function_in_c(hs_callback cb);
```
`foo.c:`
```c
#include "foo.h"
void function_in_c(hs_callback cb)
{
int x = 10;
cb(x);
}
```
`Foo.hs:`
```hs
module Main(main) where
import Foreign
import Foreign.C
type HsCallback = CInt -> IO ()
foreign import ccall "foo.h function_in_c"
functionInC :: FunPtr HsCallback -> IO ()
foreign import ccall "wrapper"
wrap :: HsCallback -> IO (FunPtr HsCallback)
main = do
f <- wrap $ \x -> print x
functionInC f
freeHaskellFunPtr f
```
On amd64 the output is 10, but on s390x is 0. On both machines, `sizeOf (undefined :: CInt) == sizeof(int) == 4`. When changing `HsCallback` to:
```hs
type HsCallback = Int -> IO ()
```
both produce the same, correct result, but the above seems wrong, as `sizeOf (undefined :: Int) == 8`.
This has been reproduced with both ghc-8.4 and ghc-8.2, and causes dbus to fail to build on s390x (https://github.com/rblaze/haskell-dbus/issues/26), as it relies on libxml-sax which contains the above (simplified) code.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.4.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (FFI) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Wrong size for int for callbacks into Haskell from foreign code","status":"New","operating_system":"","component":"Compiler (FFI)","related":[],"milestone":"8.6.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following code produces different results on amd64 (64-bit little endian) and s390x (64-bit big endian).\r\n\r\n`foo.h:`\r\n{{{#!c\r\ntypedef void(*hs_callback)(int x);\r\nextern void function_in_c(hs_callback cb);\r\n}}}\r\n`foo.c:`\r\n{{{#!c\r\n#include \"foo.h\"\r\n\r\nvoid function_in_c(hs_callback cb)\r\n{\r\n int x = 10;\r\n cb(x);\r\n}\r\n}}}\r\n`Foo.hs:`\r\n{{{#!hs\r\nmodule Main(main) where\r\n\r\nimport Foreign\r\nimport Foreign.C\r\n\r\ntype HsCallback = CInt -> IO ()\r\n\r\nforeign import ccall \"foo.h function_in_c\"\r\n functionInC :: FunPtr HsCallback -> IO ()\r\n\r\nforeign import ccall \"wrapper\"\r\n wrap :: HsCallback -> IO (FunPtr HsCallback)\r\n\r\nmain = do\r\n f <- wrap $ \\x -> print x\r\n functionInC f\r\n freeHaskellFunPtr f\r\n}}}\r\n\r\nOn amd64 the output is 10, but on s390x is 0. On both machines, `sizeOf (undefined :: CInt) == sizeof(int) == 4`. When changing `HsCallback` to:\r\n{{{#!hs\r\ntype HsCallback = Int -> IO ()\r\n}}}\r\nboth produce the same, correct result, but the above seems wrong, as `sizeOf (undefined :: Int) == 8`.\r\n\r\nThis has been reproduced with both ghc-8.4 and ghc-8.2, and causes dbus to fail to build on s390x (https://github.com/rblaze/haskell-dbus/issues/26), as it relies on libxml-sax which contains the above (simplified) code.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.6.3Peter Trommlerptrommler@acm.orgPeter Trommlerptrommler@acm.orghttps://gitlab.haskell.org/ghc/ghc/-/issues/14251LLVM Code Gen messes up registers2020-06-04T18:29:12ZMoritz AngermannLLVM Code Gen messes up registersDue to the way the LLVM Code Gen generates Function Singnatures, it is possible to end up mixed up registers.
A slightly adapted T8064
```hs
{-# LANGUAGE MagicHash, BangPatterns #-}
module Main where
import GHC.Exts
{-# NOINLINE f #-...Due to the way the LLVM Code Gen generates Function Singnatures, it is possible to end up mixed up registers.
A slightly adapted T8064
```hs
{-# LANGUAGE MagicHash, BangPatterns #-}
module Main where
import GHC.Exts
{-# NOINLINE f #-}
f :: (Int# -> Float# -> Double# -> Float# -> Double# -> String) -> String
f g = g 3# 4.0# 5.0## 6.0# 6.9## ++ " World!"
{-# NOINLINE p #-}
p :: Int# -> Float# -> Double# -> Float# -> Double# -> String
p i j k l m = "Hello"
{-# NOINLINE q #-}
q :: Int# -> Int# -> Float# -> Double# -> Float# -> Double# -> String
q _ i j k l m = "Hello " ++ show (F# l) ++ " " ++ show (D# m)
{-# NOINLINE r #-}
r :: Int# -> Float# -> Double# -> Float# -> Double# -> String
r i = let !(I# z) = length [I# 1# .. I# i] in \j k l m -> p z j k l m
-- ghc won't eta-expand around the length, because it has unknown cost
main = do
putStrLn (f p) -- fast call
putStrLn (f r) -- slow call: function but wrong arity
let g = last [q 1#]
putStrLn (f g) -- slow call: thunk
```
will produce the following results:
```
../inplace/bin/ghc-stage1 -fllvm -fforce-recomp T6084.hs -O2 -o T6084-llvm && ./T6084-llvm
[1 of 1] Compiling Main ( T6084.hs, T6084.o )
Linking T6084-llvm ...
Hello World!
Hello World!
Hello 4.0 5.0 World!
../inplace/bin/ghc-stage1 -fasm -fforce-recomp T6084.hs -O2 -o T6084-asm && ./T6084-asm
[1 of 1] Compiling Main ( T6084.hs, T6084.o )
Linking T6084-asm ...
Hello World!
Hello World!
Hello 6.0 6.9 World!
```
The underlying reason is that (at least for X86_64) the Float and Double registers alternate.
The llvm code gen creates function signatures based on the live registers (instead of all).
For `q` only the last Float and Double register are `live`. However when calling `q` we pass
`f1: Float -> d1: Double -> f2: Float -> d2: Double`. `f2` and `d2` are silently ignored, and in
the function body, we now have `f2 <- f1` and `d2 <- d1`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------------- |
| Version | 8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | highest |
| Resolution | Unresolved |
| Component | Compiler (LLVM) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | bgamari, carter, simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"LLVM Code Gen messes up registers","status":"New","operating_system":"","component":"Compiler (LLVM)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["bgamari","carter","simonmar"],"type":"Bug","description":"Due to the way the LLVM Code Gen generates Function Singnatures, it is possible to end up mixed up registers.\r\n\r\nA slightly adapted T8064\r\n{{{#!hs\r\n{-# LANGUAGE MagicHash, BangPatterns #-}\r\nmodule Main where\r\n\r\nimport GHC.Exts\r\n\r\n{-# NOINLINE f #-}\r\nf :: (Int# -> Float# -> Double# -> Float# -> Double# -> String) -> String\r\nf g = g 3# 4.0# 5.0## 6.0# 6.9## ++ \" World!\"\r\n\r\n{-# NOINLINE p #-}\r\np :: Int# -> Float# -> Double# -> Float# -> Double# -> String\r\np i j k l m = \"Hello\"\r\n\r\n{-# NOINLINE q #-}\r\nq :: Int# -> Int# -> Float# -> Double# -> Float# -> Double# -> String\r\nq _ i j k l m = \"Hello \" ++ show (F# l) ++ \" \" ++ show (D# m)\r\n\r\n{-# NOINLINE r #-}\r\nr :: Int# -> Float# -> Double# -> Float# -> Double# -> String\r\nr i = let !(I# z) = length [I# 1# .. I# i] in \\j k l m -> p z j k l m\r\n -- ghc won't eta-expand around the length, because it has unknown cost\r\n\r\nmain = do\r\n putStrLn (f p) -- fast call\r\n putStrLn (f r) -- slow call: function but wrong arity\r\n let g = last [q 1#]\r\n putStrLn (f g) -- slow call: thunk\r\n}}}\r\n\r\nwill produce the following results:\r\n\r\n{{{\r\n../inplace/bin/ghc-stage1 -fllvm -fforce-recomp T6084.hs -O2 -o T6084-llvm && ./T6084-llvm\r\n[1 of 1] Compiling Main ( T6084.hs, T6084.o )\r\nLinking T6084-llvm ...\r\nHello World!\r\nHello World!\r\nHello 4.0 5.0 World!\r\n\r\n../inplace/bin/ghc-stage1 -fasm -fforce-recomp T6084.hs -O2 -o T6084-asm && ./T6084-asm\r\n[1 of 1] Compiling Main ( T6084.hs, T6084.o )\r\nLinking T6084-asm ...\r\nHello World!\r\nHello World!\r\nHello 6.0 6.9 World!\r\n}}}\r\n\r\nThe underlying reason is that (at least for X86_64) the Float and Double registers alternate.\r\nThe llvm code gen creates function signatures based on the live registers (instead of all).\r\n\r\nFor `q` only the last Float and Double register are `live`. However when calling `q` we pass\r\n`f1: Float -> d1: Double -> f2: Float -> d2: Double`. `f2` and `d2` are silently ignored, and in\r\nthe function body, we now have `f2 <- f1` and `d2 <- d1`.","type_of_failure":"OtherFailure","blocking":[]} -->8.10.1Kavon FarvardinKavon Farvardinhttps://gitlab.haskell.org/ghc/ghc/-/issues/18269Closure size functions will return incorrect for closures with static links2020-06-02T14:12:21ZÖmer Sinan AğacanClosure size functions will return incorrect for closures with static linksNot sure if this is a bug or not, but here goes.
Closure size functions like `closureSize#` (primop) and `closure_size` (C function) don't take static link fields into account, so they will return incorrect result for top-level construc...Not sure if this is a bug or not, but here goes.
Closure size functions like `closureSize#` (primop) and `closure_size` (C function) don't take static link fields into account, so they will return incorrect result for top-level constructors (e.g. SRTs, or CAFFY constructors).
It seems like the assumption here is they'll always be passed heap-allocated closures, but as far as I can see this fact is not documented, e.g. in `ghc-heap`'s `closureSize`:
```haskell
-- | Get the size of the top-level closure in words.
-- Includes header and payload. Does not follow pointers.
--
-- @since 8.10.1
closureSize :: Box -> Int
closureSize (Box x) = I# (closureSize# x)
```
Note that, confusingly, "top-level" here means that the function does not recursively visit payloads, not that the closure is actually top-level!https://gitlab.haskell.org/ghc/ghc/-/issues/15736Testsuite failures from validate --slow2020-05-31T16:39:47Zjrp2014Testsuite failures from validate --slowIn case it helps, I ran a `./validate --slow` on HEAD on Ubuntu Bionic with 8.6.1. I don't attach much weight to the performance / stat failures as the tests seem to run in parallel. I'll pull out more specific diagnostics, if necessary....In case it helps, I ran a `./validate --slow` on HEAD on Ubuntu Bionic with 8.6.1. I don't attach much weight to the performance / stat failures as the tests seem to run in parallel. I'll pull out more specific diagnostics, if necessary.
```
==== STAGE 1 TESTS ====
SUMMARY for test run started at Wed Oct 10 20:29:33 2018 BST
0:00:04 spent to go through
2 total tests, which gave rise to
10 test cases, of which
0 were skipped
0 had missing libraries
10 expected passes
0 expected failures
0 caused framework failures
0 caused framework warnings
0 unexpected passes
0 unexpected failures
0 unexpected stat failures
==== STAGE 2 TESTS ====
Unexpected results from:
TEST="EtaExpandLevPoly T14936 T15349 T2783 T4334 T7919 haddock.Cabal haddock.base haddock.compiler hpc_fork plugin-recomp-change plugin-recomp-change-prof recomp007 space_leak_001"
SUMMARY for test run started at Wed Oct 10 19:31:20 2018 BST
0:58:10 spent to go through
6596 total tests, which gave rise to
29689 test cases, of which
5881 were skipped
256 had missing libraries
23273 expected passes
257 expected failures
0 caused framework failures
0 caused framework warnings
3 unexpected passes
6 unexpected failures
13 unexpected stat failures
Unexpected passes:
/tmp/ghctest-kyex1v3_/test spaces/rts/T2783.run T2783 [unexpected] (threaded1)
/tmp/ghctest-kyex1v3_/test spaces/typecheck/should_run/EtaExpandLevPoly.run EtaExpandLevPoly [unexpected] (profasm)
/tmp/ghctest-kyex1v3_/test spaces/typecheck/should_run/EtaExpandLevPoly.run EtaExpandLevPoly [unexpected] (profthreaded)
Unexpected failures:
/tmp/ghctest-kyex1v3_/test spaces/driver/recomp007/recomp007.run recomp007 [bad stderr] (normal)
/tmp/ghctest-kyex1v3_/test spaces/plugins/plugin-recomp-change.run plugin-recomp-change [bad stderr] (normal)
/tmp/ghctest-kyex1v3_/test spaces/plugins/plugin-recomp-change-prof.run plugin-recomp-change-prof [bad stderr] (normal)
/tmp/ghctest-kyex1v3_/test spaces/rts/T7919.run T7919 [bad exit code] (ghci)
/tmp/ghctest-kyex1v3_/test spaces/libraries/hpc/tests/fork/hpc_fork.run hpc_fork [bad heap profile] (profasm)
/tmp/ghctest-kyex1v3_/test spaces/libraries/base/tests/T15349.run T15349 [bad exit code] (ghci)
Unexpected stat failures:
/tmp/ghctest-kyex1v3_/test spaces/perf/haddock/haddock.base.run haddock.base [stat not good enough] (normal)
/tmp/ghctest-kyex1v3_/test spaces/perf/haddock/haddock.Cabal.run haddock.Cabal [stat not good enough] (normal)
/tmp/ghctest-kyex1v3_/test spaces/perf/haddock/haddock.compiler.run haddock.compiler [stat not good enough] (normal)
/tmp/ghctest-kyex1v3_/test spaces/perf/should_run/T14936.run T14936 [stat not good enough] (hpc)
/tmp/ghctest-kyex1v3_/test spaces/perf/should_run/T14936.run T14936 [stat not good enough] (profasm)
/tmp/ghctest-kyex1v3_/test spaces/perf/space_leaks/space_leak_001.run space_leak_001 [stat too good] (hpc)
/tmp/ghctest-kyex1v3_/test spaces/perf/space_leaks/space_leak_001.run space_leak_001 [stat too good] (optasm)
/tmp/ghctest-kyex1v3_/test spaces/perf/space_leaks/T4334.run T4334 [stat not good enough] (threaded2)
/tmp/ghctest-kyex1v3_/test spaces/perf/space_leaks/space_leak_001.run space_leak_001 [stat too good] (dyn)
/tmp/ghctest-kyex1v3_/test spaces/perf/space_leaks/space_leak_001.run space_leak_001 [stat too good] (optllvm)
/tmp/ghctest-kyex1v3_/test spaces/perf/should_run/T14936.run T14936 [stat not good enough] (threaded1)
/tmp/ghctest-kyex1v3_/test spaces/perf/should_run/T14936.run T14936 [stat not good enough] (threaded2)
/tmp/ghctest-kyex1v3_/test spaces/perf/should_run/T14936.run T14936 [stat not good enough] (profthreaded)
== Start post-testsuite package check
GHC package manager version 8.7.20181010
Timestamp 2018-10-10 18:31:15.21573855 UTC for /home/jrp/Projects/ghc/bindisttest/install dir/lib/ghc-8.7.20181010/package.conf.d/package.cache
using cache: /home/jrp/Projects/ghc/bindisttest/install dir/lib/ghc-8.7.20181010/package.conf.d/package.cache
db stack: ["/home/jrp/.ghc/x86_64-linux-8.7.20181010/package.conf.d","/home/jrp/Projects/ghc/bindisttest/install dir/lib/ghc-8.7.20181010/package.conf.d"]
flag db stack: ["/home/jrp/.ghc/x86_64-linux-8.7.20181010/package.conf.d","/home/jrp/Projects/ghc/bindisttest/install dir/lib/ghc-8.7.20181010/package.conf.d"]
== End post-testsuite package check
-------------------------------------------------------------------
Oops! Looks like you have some unexpected test results or framework failures.
Please fix them before pushing/sending patches.
-------------------------------------------------------------------
```https://gitlab.haskell.org/ghc/ghc/-/issues/7411Exceptions are optimized away in certain situations2020-05-27T16:04:30ZSimon Hengelsol@typeful.netExceptions are optimized away in certain situationsThe issue came up in [this thread on glasgow-haskell-users](http://www.haskell.org/pipermail/glasgow-haskell-users/2012-November/023027.html).
## Steps to reproduce:
```hs
-- file Foo.hs
import Control.Exception
import Control.DeepSeq
...The issue came up in [this thread on glasgow-haskell-users](http://www.haskell.org/pipermail/glasgow-haskell-users/2012-November/023027.html).
## Steps to reproduce:
```hs
-- file Foo.hs
import Control.Exception
import Control.DeepSeq
main = evaluate (('a' : undefined) `deepseq` return () :: IO ())
```
```
$ ghc -fforce-recomp -fpedantic-bottoms -O Foo.hs
```
### Expected result:
The program should fail with:
```
Foo: Prelude.undefined
```
### Actual result:
The program succeeds.
Compiling the program with `-fno-state-hack` helps.8.10.2Tobias Dammerstdammers@gmail.comTobias Dammerstdammers@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/9395Debug.Trace should not use %s for format string2020-04-10T18:05:46ZEdward Z. YangDebug.Trace should not use %s for format stringThe current implementation of traceIO in Debug.Trace is as follows:
```
traceIO :: String -> IO ()
traceIO msg = do
withCString "%s\n" $ \cfmt ->
withCString msg $ \cmsg ->
debugBelch cfmt cmsg
```
This is bad news: it ...The current implementation of traceIO in Debug.Trace is as follows:
```
traceIO :: String -> IO ()
traceIO msg = do
withCString "%s\n" $ \cfmt ->
withCString msg $ \cmsg ->
debugBelch cfmt cmsg
```
This is bad news: it means if the String has a null in it, the string will be silently truncated. For example, in GHC, this means that you cannot pretty-print FastString uniques, since the default printing algorithm often results in a null.
Probably the proper thing to do here is to also pass a length indicator for the CString. We should also fix unique pretty-printing to never generate nulls. A good test case would be:
```
main = trace "\0foo" (return ())
```
which should have non-empty output.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | ekmett, hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Debug.Trace should not use %s for format string","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["ekmett","hvr"],"type":"Bug","description":"The current implementation of traceIO in Debug.Trace is as follows:\r\n\r\n{{{\r\ntraceIO :: String -> IO ()\r\ntraceIO msg = do\r\n withCString \"%s\\n\" $ \\cfmt ->\r\n withCString msg $ \\cmsg ->\r\n debugBelch cfmt cmsg\r\n}}}\r\n\r\nThis is bad news: it means if the String has a null in it, the string will be silently truncated. For example, in GHC, this means that you cannot pretty-print FastString uniques, since the default printing algorithm often results in a null.\r\n\r\nProbably the proper thing to do here is to also pass a length indicator for the CString. We should also fix unique pretty-printing to never generate nulls. A good test case would be:\r\n\r\n{{{\r\nmain = trace \"\\0foo\" (return ())\r\n}}}\r\n\r\nwhich should have non-empty output.","type_of_failure":"OtherFailure","blocking":[]} -->Edward Z. YangEdward Z. Yanghttps://gitlab.haskell.org/ghc/ghc/-/issues/11555catch _|_ breaks at -O12020-04-02T11:39:30ZSergei Trofimovichcatch _|_ breaks at -O1Discovered on xmonad-0.12 test failure.
Happens on today's -HEAD and ghc-8.0.1-rc1,-rc2
Short example is (needs only base):
```hs
-- cat F.hs
module F where
import qualified Control.Exception as C
import System.IO.Unsafe
import qualif...Discovered on xmonad-0.12 test failure.
Happens on today's -HEAD and ghc-8.0.1-rc1,-rc2
Short example is (needs only base):
```hs
-- cat F.hs
module F where
import qualified Control.Exception as C
import System.IO.Unsafe
import qualified Data.List as L
abort :: String -> a
abort x = error $ "xmonad: StackSet: " ++ x
prop_abort x = unsafePerformIO $ C.catch (abort "fail")
(\(C.SomeException e) ->
return $ "xmonad: StackSet: fail" `L.isPrefixOf` show e )
where
_ = x :: Int
```
Session 1 \[ok\]:
```
$ ghci F.hs
GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling F ( F.hs, interpreted )
Ok, modules loaded: F.
*F> prop_abort 1
True
```
Session 2 \[fails\]:
```
$ ghci -O1 -fobject-code F.hs
GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling F ( F.hs, F.o )
Ok, modules loaded: F.
Prelude F> prop_abort 1
*** Exception: xmonad: StackSet: fail
CallStack (from HasCallStack):
error, called at F.hs:9:11 in main:F
```
I would expect exception to be caught on both cases.
Is it unreasonable expectation in light of unsafePerformIO?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.0.1-rc2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonpj |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"catch under unsafePerformIO breaks on -O1","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1-rc2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonpj"],"type":"Bug","description":"Discovered on xmonad-0.12 test failure.\r\nHappens on today's -HEAD and ghc-8.0.1-rc1,-rc2\r\n\r\nShort example is (needs only base):\r\n{{{#!hs\r\n-- cat F.hs\r\nmodule F where\r\n\r\nimport qualified Control.Exception as C\r\nimport System.IO.Unsafe\r\nimport qualified Data.List as L\r\n\r\nabort :: String -> a\r\nabort x = error $ \"xmonad: StackSet: \" ++ x\r\n\r\nprop_abort x = unsafePerformIO $ C.catch (abort \"fail\")\r\n (\\(C.SomeException e) ->\r\n return $ \"xmonad: StackSet: fail\" `L.isPrefixOf` show e )\r\n where\r\n _ = x :: Int\r\n}}}\r\n\r\nSession 1 [ok]:\r\n{{{\r\n$ ghci F.hs\r\n\r\nGHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help\r\n[1 of 1] Compiling F ( F.hs, interpreted )\r\nOk, modules loaded: F.\r\n\r\n*F> prop_abort 1\r\nTrue\r\n}}}\r\n\r\nSession 2 [fails]:\r\n{{{\r\n$ ghci -O1 -fobject-code F.hs\r\n\r\nGHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help\r\n[1 of 1] Compiling F ( F.hs, F.o )\r\nOk, modules loaded: F.\r\n\r\nPrelude F> prop_abort 1\r\n*** Exception: xmonad: StackSet: fail\r\nCallStack (from HasCallStack):\r\n error, called at F.hs:9:11 in main:F\r\n}}}\r\n\r\nI would expect exception to be caught on both cases.\r\nIs it unreasonable expectation in light of unsafePerformIO?\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/17970Global variables in GHC.IO.Encoding have inappropriate inlinings2020-03-31T14:58:34ZBen GamariGlobal variables in GHC.IO.Encoding have inappropriate inliningsWhile looking into #17947 I noticed that `GHC.IO.Encoding.getFileSystemEncoding` and friends, which are supposed to be global variables, exposes an unfolding:
```haskell
$ _build/stage1/bin/ghc --show-iface _build/stage1/libraries/base/b...While looking into #17947 I noticed that `GHC.IO.Encoding.getFileSystemEncoding` and friends, which are supposed to be global variables, exposes an unfolding:
```haskell
$ _build/stage1/bin/ghc --show-iface _build/stage1/libraries/base/build/GHC/IO/Encoding.hi
...
c5f268cd1abea1e17607b29083a07ddf
getFileSystemEncoding ::
GHC.Types.IO GHC.IO.Encoding.Types.TextEncoding
[Unfolding: (case getFileSystemEncoding1 of wild { (,) getFileSystemEncoding81 setFileSystemEncoding1 ->
getFileSystemEncoding81 })]
877b4ce4c0c06df59a38c01a0a2f65ea
getFileSystemEncoding1 ::
(GHC.Types.IO GHC.IO.Encoding.Types.TextEncoding,
GHC.IO.Encoding.Types.TextEncoding -> GHC.Types.IO ())
[Unfolding: (case GHC.Magic.runRW#
@('GHC.Types.TupleRep
'[ 'GHC.Types.TupleRep '[], 'GHC.Types.LiftedRep])
@(# GHC.Prim.State# GHC.Prim.RealWorld,
(GHC.Types.IO GHC.IO.Encoding.Types.TextEncoding,
GHC.IO.Encoding.Types.TextEncoding -> GHC.Types.IO ()) #)
getFileSystemEncoding2 of ds { (#,#) ipv ipv1 ->
ipv1 })]
...
01c6dd64e835d1d407d95b7dea54fa17
getFileSystemEncoding2 ::
GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld,
(GHC.Types.IO GHC.IO.Encoding.Types.TextEncoding,
GHC.IO.Encoding.Types.TextEncoding -> GHC.Types.IO ()) #)
[Arity: 1, Strictness: <L,U>,
Unfolding: (\ (s :: GHC.Prim.State# GHC.Prim.RealWorld)[OneShot] ->
case GHC.Prim.noDuplicate# @GHC.Prim.RealWorld s of s' { DEFAULT ->
case GHC.Prim.newMutVar#
@GHC.IO.Encoding.Types.TextEncoding
@GHC.Prim.RealWorld
getFileSystemEncoding3
s' of ds { (#,#) ipv ipv1 ->
(# ipv,
((\ (eta :: GHC.Prim.State# GHC.Prim.RealWorld) ->
GHC.Prim.readMutVar#
@GHC.Prim.RealWorld
@GHC.IO.Encoding.Types.TextEncoding
ipv1
eta)
`cast`
(Sym (GHC.Types.N:IO[0] <GHC.IO.Encoding.Types.TextEncoding>_R)),
(\ (v :: GHC.IO.Encoding.Types.TextEncoding)
(eta :: GHC.Prim.State# GHC.Prim.RealWorld) ->
case GHC.Prim.writeMutVar#
@GHC.Prim.RealWorld
@GHC.IO.Encoding.Types.TextEncoding
ipv1
v
eta of s2# { DEFAULT ->
(# s2#, GHC.Tuple.() #) })
`cast`
(<GHC.IO.Encoding.Types.TextEncoding>_R
->_R Sym (GHC.Types.N:IO[0] <()>_R))) #) } })]
```
This will break the "globalness" of these variables, potentially breaking `setFileSystemEncoding` and others.8.10.2Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/7364`foo !f = id . f` becomes non-strict with -O22020-02-26T21:26:36Zshachaf`foo !f = id . f` becomes non-strict with -O2The following program:
```
foo :: (a -> b) -> a -> b
foo !f = id . f
main :: IO ()
main = print (foo undefined `seq` "ok")
```
Crashes with `Prelude.undefined` when compiled without `-O2`, but prints `"ok"` with it. As far as I can te...The following program:
```
foo :: (a -> b) -> a -> b
foo !f = id . f
main :: IO ()
main = print (foo undefined `seq` "ok")
```
Crashes with `Prelude.undefined` when compiled without `-O2`, but prints `"ok"` with it. As far as I can tell the optimizer shouldn't be allowed to do that.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.6.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":"`foo !f = id . f` becomes non-strict with -O2","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following program:\r\n\r\n{{{\r\nfoo :: (a -> b) -> a -> b\r\nfoo !f = id . f\r\n\r\nmain :: IO ()\r\nmain = print (foo undefined `seq` \"ok\")\r\n}}}\r\n\r\nCrashes with `Prelude.undefined` when compiled without `-O2`, but prints `\"ok\"` with it. As far as I can tell the optimizer shouldn't be allowed to do that.","type_of_failure":"OtherFailure","blocking":[]} -->https://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/16514Fix for #14619 is wrong2020-02-25T01:14:44ZDuane RyragFix for #14619 is wrongThe fix for #14619 is wrong. Please see https://gitlab.haskell.org/ghc/ghc/commit/add4e1f11b88cd603f6c01bc135eb576e1922a8e#note_190830.The fix for #14619 is wrong. Please see https://gitlab.haskell.org/ghc/ghc/commit/add4e1f11b88cd603f6c01bc135eb576e1922a8e#note_190830.8.6.5https://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/15732getArgsWithResponseFiles does not filter out RTS options2020-01-23T19:38:56ZChaitanya Koparkarckoparkar@gmail.comgetArgsWithResponseFiles does not filter out RTS optionsI discovered this while working on a fix for #15072.
`GHC.ResponseFile.getArgsWithResponseFiles` is a recent addition to `base-4.12`. The idea was to have a function which could read command-line arguments supplied via response files, b...I discovered this while working on a fix for #15072.
`GHC.ResponseFile.getArgsWithResponseFiles` is a recent addition to `base-4.12`. The idea was to have a function which could read command-line arguments supplied via response files, but otherwise
would behave exactly like `System.Environment.getArgs` (see #13896). However, these functions return different results when RTS options are supplied.
1. `getArgs` does not include RTS options in the list it returns.
1. `getArgsWithResponseFiles` includes them.
It's trivial to reproduce this. Consider these files:
```
-- Bug1.hs
module Main where
import System.Environment ( getArgs )
main :: IO ()
main = do
args <- getArgs
putStrLn $ "Args: " ++ show args
```
and
```
-- Bug2.hs
module Main where
import GHC.ResponseFile ( getArgsWithResponseFiles )
main :: IO ()
main = do
args <- getArgsWithResponseFiles
putStrLn $ "ArgsResp: " ++ show args
```
And run them with:
```sh
$ ghc-8.6.1 -rtsopts Bug1.hs && ghc-8.6.1 -rtsopts Bug2.hs
$ ./Bug1 1 +RTS -H32m -RTS 10 20
Args: ["1","10","20"]
-- 'opts_file' contains the same arguments passed to Bug1, and we
-- use a '@' to pass it as a response file
$ ./Bug2 @opts_file
ArgsResp: ["1","+RTS","-H32m","-RTS","10","20"]
```
We should fix `getArgsWithResponseFiles` to properly handle `+RTS ... -RTS` and `--RTS` flags. `getArgs` relies on the [runtime system](http://git.haskell.org/ghc.git/blob/HEAD:/rts/RtsFlags.c#l661) for this.