GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2021-11-15T21:21:26Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/10160GHCi :sprint has odd/unhelpful behavior for values defined within the REPL2021-11-15T21:21:26ZbitemyappGHCi :sprint has odd/unhelpful behavior for values defined within the REPLWanted to use :sprint to help learners visualise thunk evaluation behavior in their data. Ran into some behaviors that a few people I checked with didn't have a good explanation for. I couldn't find anything in the user guide to explain ...Wanted to use :sprint to help learners visualise thunk evaluation behavior in their data. Ran into some behaviors that a few people I checked with didn't have a good explanation for. I couldn't find anything in the user guide to explain this. I don't think it technically violates Haskell Report requirements, but it makes :sprint considerably less useful if you're teaching somebody non-strictness.
Examples with code in the REPL:
```
Prelude> let x = [1, 2, 3 :: Integer]
Prelude> :sprint x
x = [1,2,3]
-- errr, what?
Prelude> let x = Just (1 :: Integer)
Prelude> :sprint x
x = Just 1
Prelude> let just = Just
Prelude> let x = just (1 :: Integer)
Prelude> :sprint x
x = _
Prelude> let x = Just (undefined :: Integer)
Prelude> :sprint x
x = Just _
Prelude> let x = just (undefined :: Integer)
Prelude> :sprint x
x = _
Prelude> let x = [1, 2, 3 :: Integer]
Prelude> let y = x
Prelude> :sprint y
y = [1,2,3]
Prelude> let x = 1 : 2 : (3 :: Integer) : []
Prelude> :sprint x
x = [1,2,3]
Prelude> let x = [1] ++ [2] ++ [(3 :: Integer)]
Prelude> :sprint x
x = _
Prelude> let y = (:)
Prelude> let x = 1 `y` (2 `y` ((3 :: Integer) `y` []))
Prelude> :sprint x
x = _
Prelude> x
[1,2,3]
Prelude> :sprint x
x = [1,2,3]
```
So the behavior here seems to be:
Constructors used directly in the construction of data and are not passed functions (including polymorphic vals awaiting concrete instances)/bottoms are immediately evaluated
Example, but with loading data from a file:
Contents of the file:
```
x :: Num a => [a]
x = [1, 2, 3]
```
GHCi session:
```
Prelude> :t x
x :: Num a => [a]
Prelude> :sprint x
x = _
Prelude> x
[1,2,3]
Prelude> :sprint x
x = _
-- ^^ this is expected
```
Then when x is loaded from a file, but has a different type:
```
Prelude> :t x
x :: [Integer]
Prelude> :sprint x
x = _
Prelude> head x
1
Prelude> :sprint x
x = [1,2,3]
-- ^^ this is not
```
Now, this is a bit confusing. Earlier I was able to get :sprint to return \[1, _, _\] when I evaluated head x, but a couple hours later when I went to write this ticket, I couldn't reproduce that behavior.
Is there documentation that explains:
1. Why data is shown as having been evaluated at time of declaration (seemingly) by :sprint when it's defined in the GHCi
1. Why declaring code in GHCi and loading it from a file behaves differently with :sprint (I considered let expression in the implicit GHCi do-block...couldn't find anything to explain this)
1. Why evaluating 'head x' forces the other values as well
Are any of these behaviors a bug? If not, are they documented anywhere? Is the "eager" treatment of constructors in GHCi a performance thing? That seems strange given I didn't have -fobject-code turned on.
:sprint not demonstrating semantics that match what I expect from a non-strict language hinders its utility as a teaching tool and means the only robust option for learners that I can find is testing evaluation with bottom values.
```
-- So that you know i picked "7.8.4" as the version consciously
[callen@atlantis ~/Work/fpbook]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.4
[callen@atlantis ~/Work/fpbook]$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 7.8.4
```https://gitlab.haskell.org/ghc/ghc/-/issues/10111hp2ps silently discards samples2019-07-07T18:37:27ZEdward Z. Yanghp2ps silently discards samplesConsider the following hp file:
```
JOB "whatever"
DATE "Sat Feb 21 12:56 2015"
SAMPLE_UNIT "seconds"
VALUE_UNIT "bytes"
BEGIN_SAMPLE 0.00
MAIN 1000
END_SAMPLE 0.00
BEGIN_SAMPLE 0.00
MAIN 100
END_SAMPLE 0.00
BEGIN_SAMPLE 0.01
MAIN 500
E...Consider the following hp file:
```
JOB "whatever"
DATE "Sat Feb 21 12:56 2015"
SAMPLE_UNIT "seconds"
VALUE_UNIT "bytes"
BEGIN_SAMPLE 0.00
MAIN 1000
END_SAMPLE 0.00
BEGIN_SAMPLE 0.00
MAIN 100
END_SAMPLE 0.00
BEGIN_SAMPLE 0.01
MAIN 500
END_SAMPLE 0.01
```
hp2ps will generate a graph showing heap usage going from 100 bytes to 500 bytes... not 1000-100-500 as expected. This is because hp2ps only uses the last sample with the same timestamp.
These hp files show in practice because GHC doesn't output BEGIN_SAMPLE entries with enough precision, see also https://phabricator.haskell.org/D679 to increase the precision.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.11 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Profiling |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"hp2ps silently discards samples","status":"New","operating_system":"","component":"Profiling","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.11","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following hp file:\r\n\r\n{{{\r\nJOB \"whatever\"\r\nDATE \"Sat Feb 21 12:56 2015\"\r\nSAMPLE_UNIT \"seconds\"\r\nVALUE_UNIT \"bytes\"\r\nBEGIN_SAMPLE 0.00\r\nMAIN\t1000\r\nEND_SAMPLE 0.00\r\nBEGIN_SAMPLE 0.00\r\nMAIN\t100\r\nEND_SAMPLE 0.00\r\nBEGIN_SAMPLE 0.01\r\nMAIN\t500\r\nEND_SAMPLE 0.01\r\n}}}\r\n\r\nhp2ps will generate a graph showing heap usage going from 100 bytes to 500 bytes... not 1000-100-500 as expected. This is because hp2ps only uses the last sample with the same timestamp.\r\n\r\nThese hp files show in practice because GHC doesn't output BEGIN_SAMPLE entries with enough precision, see also https://phabricator.haskell.org/D679 to increase the precision.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/10046Linker script patch in rts/Linker.c doesn't work for (non-C or non-en..) locales2019-07-07T18:37:48ZHoward B. GoldenLinker script patch in rts/Linker.c doesn't work for (non-C or non-en..) localesPlease see [ticket:2615\#comment:95729](https://gitlab.haskell.org//ghc/ghc/issues/2615#note_95729) and replies.
A bug is illustrated by this Haskell program:
```
import ObjLink
import Foreign
import Foreign.C.Types
import Foreign.C.St...Please see [ticket:2615\#comment:95729](https://gitlab.haskell.org//ghc/ghc/issues/2615#note_95729) and replies.
A bug is illustrated by this Haskell program:
```
import ObjLink
import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import ccall "setlocale" c_setlocale :: CInt -> CString -> IO CString
main = do
withCString "zh_CN.UTF-8" $ \lc -> c_setlocale 5 lc
r <- loadDLL "/usr/lib/libc.so"
putStrLn (show r)
```
which outputs:
```
Just "/usr/lib/libc.so: \26080\25928\30340 ELF \22836"
```
The "\\26080\\25928\\30340 ELF \\22836" part is "无效的ELF头" in Chinese.
This error only occurs on systems where linker scripts are used. The linker script patch (as it has evolved) assumes that the error messages it will receive are in English. This would be true if the locale (LC_MESSAGES) is C or en (or one of the en variants). However, in other locales, the message will be in a different language. Unfortunately, the semantics of POSIX dlerror() specify that the error is returned as a pointer to a human-readable text string, rather than an error code. The string returned depends on the locale.
The code could be made more robust by momentarily changing the locale (LC_MESSAGES) to C before calling dlerror() and reverting it to its previous value immediately after. This has been tested on a zh_CN.utf-8 (see [ticket:2615\#comment:95752](https://gitlab.haskell.org//ghc/ghc/issues/2615#note_95752)) and works. The only concern I have is in the case of multithreaded code that _might_ be affected if it is running while the locale is changed. I don't know enough to know if this is a real issue or not, nor do I know how to deal with it if necessary.
Also see #9237 for another corner case in the linker script code that should be dealt with at the same time.8.0.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9936Data.Fixed truncates 5.17 to 5.162019-07-07T18:38:21ZsingpolymaData.Fixed truncates 5.17 to 5.16`(realToFrac (5.17 :: Double) :: Centi) == 5.16`
is true -- it should be false.
The offender seems to be the assumption in `fromRational`:
`fromRational r = withResolution (\res -> MkFixed (floor (r * (toRational res))))`
Uses `floor`...`(realToFrac (5.17 :: Double) :: Centi) == 5.16`
is true -- it should be false.
The offender seems to be the assumption in `fromRational`:
`fromRational r = withResolution (\res -> MkFixed (floor (r * (toRational res))))`
Uses `floor` assuming that the underlying floating point value is stored purely and not as 0.999999 or similar -- switching it to `round` fixes this issue.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.3 |
| 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":"Data.Fixed truncates 5.17 to 5.16","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["ekmett","hvr"],"type":"Bug","description":"`(realToFrac (5.17 :: Double) :: Centi) == 5.16`\r\nis true -- it should be false.\r\n\r\nThe offender seems to be the assumption in `fromRational`:\r\n\r\n`fromRational r = withResolution (\\res -> MkFixed (floor (r * (toRational res))))`\r\n\r\nUses `floor` assuming that the underlying floating point value is stored purely and not as 0.999999 or similar -- switching it to `round` fixes this issue.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9765Strange behavior of GC under ghci2019-07-07T18:39:08ZremdezxStrange behavior of GC under ghciReleasing the result of `newForeignPtr nullFunPtr nullPtr` end in core dump, due to the fact that finalizer function is set to null pointer.
When I run something like this in GHCI:
```hs
> import System.Mem
> import Foreign.Ptr
> impo...Releasing the result of `newForeignPtr nullFunPtr nullPtr` end in core dump, due to the fact that finalizer function is set to null pointer.
When I run something like this in GHCI:
```hs
> import System.Mem
> import Foreign.Ptr
> import Foreign.ForeignPtr
> import System.IO.Unsafe
> import qualified Data.Map as Map
> a <- return $ Map.singleton 1 (unsafePerformIO $ newForeignPtr nullFunPtr nullPtr)
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package containers-0.5.5.1 ... linking ... done.
> print a
fromList [(1,0x0000000000000000)]
> performGC
> ^D
Leaving GHCi.
[1] 3782 segmentation fault (core dumped) ghci
```
it wont crash until exit from ghci which is correct. But if I do something similar but using `let` binding it will crash even if variable `a` didn't lose its scope
```hs
> import System.Mem
> import Foreign.Ptr
> import Foreign.ForeignPtr
> import System.IO.Unsafe
> import qualified Data.Map as Map
> let a = Map.singleton 1 (unsafePerformIO $ newForeignPtr nullFunPtr nullPtr)
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package containers-0.5.5.1 ... linking ... done.
> print a
fromList [(1,0x0000000000000000)]
[1] 3842 segmentation fault (core dumped) ghci
```
Why is there a difference between doing it with `do` notation and with `let` binding?
I also expected that if I rebind variable `a` it will lose it's scope and will be released but it is not (see below)
```hs
> import System.Mem
> import Foreign.Ptr
> import Foreign.ForeignPtr
> import System.IO.Unsafe
> import qualified Data.Map as Map
> a <- return $ Map.singleton 1 (unsafePerformIO $ newForeignPtr nullFunPtr nullPtr)
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package containers-0.5.5.1 ... linking ... done.
> print a
fromList [(1,0x0000000000000000)]
> a <- return () -- rebinding varable a, it is no longer used
> performGC
> -- no crash, varaible a not released
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | hvr |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Strange behavior of GC under ghci","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["hvr"],"type":"Bug","description":"Releasing the result of `newForeignPtr nullFunPtr nullPtr` end in core dump, due to the fact that finalizer function is set to null pointer.\r\n\r\nWhen I run something like this in GHCI:\r\n{{{#!hs\r\n> import System.Mem\r\n> import Foreign.Ptr \r\n> import Foreign.ForeignPtr\r\n> import System.IO.Unsafe\r\n> import qualified Data.Map as Map\r\n> a <- return $ Map.singleton 1 (unsafePerformIO $ newForeignPtr nullFunPtr nullPtr)\r\nLoading package array-0.5.0.0 ... linking ... done.\r\nLoading package deepseq-1.3.0.2 ... linking ... done.\r\nLoading package containers-0.5.5.1 ... linking ... done.\r\n> print a\r\nfromList [(1,0x0000000000000000)]\r\n> performGC\r\n> ^D\r\nLeaving GHCi.\r\n[1] 3782 segmentation fault (core dumped) ghci\r\n}}}\r\n\r\nit wont crash until exit from ghci which is correct. But if I do something similar but using `let` binding it will crash even if variable `a` didn't lose its scope\r\n{{{#!hs\r\n> import System.Mem\r\n> import Foreign.Ptr \r\n> import Foreign.ForeignPtr\r\n> import System.IO.Unsafe\r\n> import qualified Data.Map as Map\r\n> let a = Map.singleton 1 (unsafePerformIO $ newForeignPtr nullFunPtr nullPtr)\r\nLoading package array-0.5.0.0 ... linking ... done.\r\nLoading package deepseq-1.3.0.2 ... linking ... done.\r\nLoading package containers-0.5.5.1 ... linking ... done.\r\n> print a\r\nfromList [(1,0x0000000000000000)]\r\n[1] 3842 segmentation fault (core dumped) ghci\r\n}}}\r\n\r\nWhy is there a difference between doing it with `do` notation and with `let` binding?\r\n\r\nI also expected that if I rebind variable `a` it will lose it's scope and will be released but it is not (see below)\r\n{{{#!hs\r\n> import System.Mem\r\n> import Foreign.Ptr \r\n> import Foreign.ForeignPtr\r\n> import System.IO.Unsafe\r\n> import qualified Data.Map as Map\r\n> a <- return $ Map.singleton 1 (unsafePerformIO $ newForeignPtr nullFunPtr nullPtr)\r\nLoading package array-0.5.0.0 ... linking ... done.\r\nLoading package deepseq-1.3.0.2 ... linking ... done.\r\nLoading package containers-0.5.5.1 ... linking ... done.\r\n> print a\r\nfromList [(1,0x0000000000000000)]\r\n> a <- return () -- rebinding varable a, it is no longer used\r\n> performGC\r\n> -- no crash, varaible a not released\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9534IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCB2019-07-07T18:40:07Zjrp2014IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCBThe attached is an implementation of the floating point accuracy test described in *The Baleful Influence of Benchmarks* section of http://www.eecs.berkeley.edu/\~wkahan/ieee754status/IEEE754.PDF
```
Results for Float:
r = 4098.0 produc...The attached is an implementation of the floating point accuracy test described in *The Baleful Influence of Benchmarks* section of http://www.eecs.berkeley.edu/\~wkahan/ieee754status/IEEE754.PDF
```
Results for Float:
r = 4098.0 produces 12.0 and 12.0 sig. bits
r = 4098.25 fails: root 0.99989897 isn't at least 1 <<<<
r = 4097.004 produces 12.0 and 11.999298 sig. bits
:
Worst accuracy is 11.999298 sig. bits
:
Results for Double:
r = 4098.0 produces Infinity and Infinity sig. bits
r = 4098.25 produces Infinity and 53.0 sig. bits
r = 4097.00390625 produces Infinity and 53.451178091541244 sig. bits
r = 1.6777218e7 produces Infinity and Infinity sig. bits
r = 1.677721825e7 produces Infinity and 75.0 sig. bits
r = 1.6777219e7 produces Infinity and 71.0 sig. bits
r = 9.4906267e7 produces 26.499999994288153 and 26.499999986733027 sig. bits
r = 9.490626725e7 fails: root 0.999999995635551 isn't at least 1 <<<
r = 2.684354505e8 produces 28.0 and 27.999999919383132 sig. bits
r = 2.684354515e8 produces 28.0 and 27.99999993013205 sig. bits
r = 2.68435458e8 produces 28.0 and 28.0 sig. bits
r = 2.6843545825e8 produces 28.0 and 28.00000000268723 sig. bits
r = 2.6843545700000006e8 produces 28.0 and 27.999999989251084 sig. bits
r = 4.294967298e9 produces 32.0 and 32.0 sig. bits
r = 4.29496729825e9 produces 32.0 and 32.00000000016795 sig. bits
Worst accuracy is 26.499999986733027 sig. bits
```
This seems to be comparable to a clang version, but seems to be fairly poor in comparison to some other machines, back in the day (1997).
**The attached could, possibly be turned into a testsuite test, by removing the QuickCheck tests that are included.**
Observations:
- There are a couple of failures (could be the implementation of sqrt or log).
- signum seems incorrect (signum Nan = -1.0)
- The prelude should have a copysign function
- min fails to produce the other argument if one argument is NaN
- The CFloat and CDouble variants seem to produce the same result as the native Float and Double versions
- The Haskell coding style could be improved to remove some boilerplate, make the code more idiomatic
- There may be a better way of entering the test values of r to ensure that they are accurate
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Test Suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"IEEE Standard 754 for Binary Floating-Point Arithmetic by Prof. W. Kahan, UCB","status":"New","operating_system":"","component":"Test Suite","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["IEEE754"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"The attached is an implementation of the floating point accuracy test described in ''The Baleful Influence of Benchmarks'' section of http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF\r\n\r\n\r\n{{{\r\nResults for Float:\r\nr = 4098.0 produces 12.0 and 12.0 sig. bits\r\nr = 4098.25 fails: root 0.99989897 isn't at least 1 <<<<\r\nr = 4097.004 produces 12.0 and 11.999298 sig. bits\r\n:\r\nWorst accuracy is 11.999298 sig. bits\r\n\r\n:\r\n\r\nResults for Double:\r\nr = 4098.0 produces Infinity and Infinity sig. bits\r\nr = 4098.25 produces Infinity and 53.0 sig. bits\r\nr = 4097.00390625 produces Infinity and 53.451178091541244 sig. bits\r\nr = 1.6777218e7 produces Infinity and Infinity sig. bits\r\nr = 1.677721825e7 produces Infinity and 75.0 sig. bits\r\nr = 1.6777219e7 produces Infinity and 71.0 sig. bits\r\nr = 9.4906267e7 produces 26.499999994288153 and 26.499999986733027 sig. bits\r\nr = 9.490626725e7 fails: root 0.999999995635551 isn't at least 1 <<<\r\nr = 2.684354505e8 produces 28.0 and 27.999999919383132 sig. bits\r\nr = 2.684354515e8 produces 28.0 and 27.99999993013205 sig. bits\r\nr = 2.68435458e8 produces 28.0 and 28.0 sig. bits\r\nr = 2.6843545825e8 produces 28.0 and 28.00000000268723 sig. bits\r\nr = 2.6843545700000006e8 produces 28.0 and 27.999999989251084 sig. bits\r\nr = 4.294967298e9 produces 32.0 and 32.0 sig. bits\r\nr = 4.29496729825e9 produces 32.0 and 32.00000000016795 sig. bits\r\nWorst accuracy is 26.499999986733027 sig. bits\r\n}}}\r\n\r\nThis seems to be comparable to a clang version, but seems to be fairly poor in comparison to some other machines, back in the day (1997).\r\n\r\n'''The attached could, possibly be turned into a testsuite test, by removing the QuickCheck tests that are included.'''\r\n\r\nObservations:\r\n\r\n* There are a couple of failures (could be the implementation of sqrt or log). \r\n* signum seems incorrect (signum Nan = -1.0)\r\n* The prelude should have a copysign function\r\n* min fails to produce the other argument if one argument is NaN\r\n* The CFloat and CDouble variants seem to produce the same result as the native Float and Double versions\r\n* The Haskell coding style could be improved to remove some boilerplate, make the code more idiomatic\r\n* There may be a better way of entering the test values of r to ensure that they are accurate\r\n\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/9406unexpected failure for T7837(profasm)2019-07-07T18:40:31Zjrp2014unexpected failure for T7837(profasm)This may be a test suite configuration error as the normal case works (and indeed I get a lot of profiled case failures of other cases). When run with an llvm-perf build of the HEAD, I get:
```
=====> T7837(normal) 1395 of 4068 [0, 0, 0...This may be a test suite configuration error as the normal case works (and indeed I get a lot of profiled case failures of other cases). When run with an llvm-perf build of the HEAD, I get:
```
=====> T7837(normal) 1395 of 4068 [0, 0, 0]
cd ./indexed-types/should_compile && '/Users/jrp/Projects/haskell/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -c T7837.hs -O -ddump-rule-firings >T7837.comp.stderr 2>&1
=====> T7837(profasm) 1395 of 4068 [0, 0, 0]
cd ./indexed-types/should_compile && '/Users/jrp/Projects/haskell/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -c T7837.hs -O -prof -static -auto-all -O -ddump-rule-firings >T7837.comp.stderr 2>&1
Actual stderr output differs from expected:
--- ./indexed-types/should_compile/T7837.stderr 2014-08-03 11:36:53.000000000 +0100
+++ ./indexed-types/should_compile/T7837.comp.stderr 2014-08-04 23:16:34.000000000 +0100
@@ -1,3 +1,4 @@
Rule fired: Class op abs
Rule fired: Class op signum
Rule fired: normalize/Double
+Rule fired: Class op /
*** unexpected failure for T7837(profasm)
Unexpected results from:
TEST="T7837"
OVERALL SUMMARY for test run started at Mon Aug 4 23:16:32 2014 BST
0:00:02 spent to go through
4068 total tests, which gave rise to
19536 test cases, of which
19534 were skipped
0 had missing libraries
1 expected passes
0 expected failures
0 caused framework failures
0 unexpected passes
1 unexpected failures
Unexpected failures:
indexed-types/should_compile T7837 [stderr mismatch] (profasm)
```https://gitlab.haskell.org/ghc/ghc/-/issues/9347forkProcess does not acquire global handle locks2019-07-07T18:40:47Zedsko@edsko.netforkProcess does not acquire global handle locksThe global I/O handles (`stdout`, `stdin`, `stderr`) all make use an `MVar` wrapping a `Handle__`, and many I/O functions temporarily take this `MVar` (for instance, functions such as `hPutStr` include a call to `wantWritableHandle`, whi...The global I/O handles (`stdout`, `stdin`, `stderr`) all make use an `MVar` wrapping a `Handle__`, and many I/O functions temporarily take this `MVar` (for instance, functions such as `hPutStr` include a call to `wantWritableHandle`, which uses `withHandle_'`, which involves taking the `MVar`, executing some operation, and then putting the `MVar` back).
Suppose we have a program consisting of two threads A and B, where thread A is doing I/O. If thread B does a call to `forkProcess` then it is possible that the `fork()` happens at the point that A has just taken, say, the `MVar` for `stdout`. If this happens, every use of `stdout` in the child process will now forever deadlock.
This is not a theoretical scenario. The example code reported by Michael Snoyman a few years ago
http://www.haskell.org/pipermail/haskell-cafe/2012-October/103922.html
exhibits precisely this behaviour: the child process deadlocks (not all the the time, but very frequently), exactly because of this problem.
In `forkProcess` we avoid this sort of situation for all of the global RTS locks by acquiring the lock just before the call to `fork()`, and then releasing the lock in the parent again and re-initializing the lock in the child. But there are no provisions for Haskell-land locks such as the above `MVar`.
In principle we can work around this problem entirely in user-land. Here is a modified version of Michael's code that does not deadlock (at least, it never has in my tests..), that basically takes the same acquire-release\*2 trick that `forkProcess` does for RTS locks in the lines marked `(*)`:
```
import System.Posix.Process (forkProcess, getProcessID)
import Control.Concurrent (forkIO, threadDelay)
import System.IO (hFlush, stdout)
import System.Posix.Signals (signalProcess, sigKILL)
import Control.Exception (finally)
import Control.Concurrent
import GHC.IO.Handle.Types
import System.IO
main :: IO ()
main = do
mapM_ spawnChild [1..9]
ioLock <- lockIO -- (*)
child <- forkProcess $ do
unlockIO ioLock -- (*)
putStrLn "starting child"
hFlush stdout
loop "child" 0
unlockIO ioLock -- (*)
print ("child pid", child)
hFlush stdout
-- I've commented out the "finally" so that the zombie process stays alive,
-- to prove that it was actually created.
loop "parent" 0 -- `finally` signalProcess sigKILL child
spawnChild :: Int -> IO ()
spawnChild i = do
_ <- forkIO $ loop ("spawnChild " ++ show i) 0
return ()
loop :: String -> Int -> IO ()
loop msg i = do
pid <- getProcessID
print (pid, msg, i)
hFlush stdout
threadDelay 1000000
loop msg (i + 1)
--------------------------------------------------------------------------------
lockIO :: IO Handle__
lockIO =
case stdout of
FileHandle _ m -> takeMVar m
unlockIO :: Handle__ -> IO ()
unlockIO hout =
case stdout of
FileHandle _ m -> putMVar m hout
```
I guess that _any_ global `MVar` or `TVar` is suspect when using `forkProcess`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.2 |
| 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":"forkProcess does not acquire global handle locks","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The global I/O handles (`stdout`, `stdin`, `stderr`) all make use an `MVar` wrapping a `Handle__`, and many I/O functions temporarily take this `MVar` (for instance, functions such as `hPutStr` include a call to `wantWritableHandle`, which uses `withHandle_'`, which involves taking the `MVar`, executing some operation, and then putting the `MVar` back).\r\n\r\nSuppose we have a program consisting of two threads A and B, where thread A is doing I/O. If thread B does a call to `forkProcess` then it is possible that the `fork()` happens at the point that A has just taken, say, the `MVar` for `stdout`. If this happens, every use of `stdout` in the child process will now forever deadlock. \r\n\r\nThis is not a theoretical scenario. The example code reported by Michael Snoyman a few years ago\r\n\r\nhttp://www.haskell.org/pipermail/haskell-cafe/2012-October/103922.html\r\n\r\nexhibits precisely this behaviour: the child process deadlocks (not all the the time, but very frequently), exactly because of this problem. \r\n\r\nIn `forkProcess` we avoid this sort of situation for all of the global RTS locks by acquiring the lock just before the call to `fork()`, and then releasing the lock in the parent again and re-initializing the lock in the child. But there are no provisions for Haskell-land locks such as the above `MVar`.\r\n\r\nIn principle we can work around this problem entirely in user-land. Here is a modified version of Michael's code that does not deadlock (at least, it never has in my tests..), that basically takes the same acquire-release*2 trick that `forkProcess` does for RTS locks in the lines marked `(*)`:\r\n\r\n{{{\r\nimport System.Posix.Process (forkProcess, getProcessID)\r\nimport Control.Concurrent (forkIO, threadDelay)\r\nimport System.IO (hFlush, stdout)\r\nimport System.Posix.Signals (signalProcess, sigKILL)\r\nimport Control.Exception (finally)\r\n\r\nimport Control.Concurrent\r\nimport GHC.IO.Handle.Types\r\nimport System.IO\r\n\r\nmain :: IO ()\r\nmain = do\r\n mapM_ spawnChild [1..9]\r\n\r\n ioLock <- lockIO -- (*)\r\n child <- forkProcess $ do\r\n unlockIO ioLock -- (*)\r\n putStrLn \"starting child\"\r\n hFlush stdout\r\n loop \"child\" 0\r\n unlockIO ioLock -- (*)\r\n\r\n print (\"child pid\", child)\r\n hFlush stdout\r\n\r\n -- I've commented out the \"finally\" so that the zombie process stays alive,\r\n -- to prove that it was actually created.\r\n loop \"parent\" 0 -- `finally` signalProcess sigKILL child\r\n\r\nspawnChild :: Int -> IO ()\r\nspawnChild i = do\r\n _ <- forkIO $ loop (\"spawnChild \" ++ show i) 0\r\n return ()\r\n\r\nloop :: String -> Int -> IO ()\r\nloop msg i = do\r\n pid <- getProcessID\r\n print (pid, msg, i)\r\n hFlush stdout\r\n threadDelay 1000000\r\n loop msg (i + 1)\r\n\r\n--------------------------------------------------------------------------------\r\n\r\nlockIO :: IO Handle__ \r\nlockIO = \r\n case stdout of\r\n FileHandle _ m -> takeMVar m \r\n\r\nunlockIO :: Handle__ -> IO ()\r\nunlockIO hout = \r\n case stdout of\r\n FileHandle _ m -> putMVar m hout\r\n}}}\r\n\r\nI guess that _any_ global `MVar` or `TVar` is suspect when using `forkProcess`. ","type_of_failure":"OtherFailure","blocking":[]} -->Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/9307LLVM vs NCG: floating point numbers close to zero have different sign2019-07-07T18:40:56Zjrp2014LLVM vs NCG: floating point numbers close to zero have different signCompiling HEAD with perf-llvm, (3.4.2) and running the nofib suite fails at the wave4main case. It is not clear to me whether wave4main should always produce the same output (and so the test fails because it does not do so) or whether th...Compiling HEAD with perf-llvm, (3.4.2) and running the nofib suite fails at the wave4main case. It is not clear to me whether wave4main should always produce the same output (and so the test fails because it does not do so) or whether the numbers generated depend on some feature of the build settings, or OS.
```
HC = /Users/xxx/Projects/ghc/inplace/bin/ghc-stage2
HC_OPTS = -O2 -Rghc-timing -H32m -hisuf hi -cpp -fglasgow-exts -rtsopts
RUNTEST_OPTS = -ghc-timing
==nofib== wave4main: size of wave4main follows...
__TEXT __DATA __OBJC others dec hex
4091904 450560 0 4295947176 4300489640 1005443a8
==nofib== wave4main: time to run wave4main follows...
../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000;
real 0m0.217s
user 0m0.191s
sys 0m0.011s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16932.1 2014-07-13 13:43:22.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.197s
user 0m0.186s
sys 0m0.008s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16961.1 2014-07-13 13:43:22.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.201s
user 0m0.189s
sys 0m0.009s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17011.1 2014-07-13 13:43:22.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.201s
user 0m0.190s
sys 0m0.008s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17051.1 2014-07-13 13:43:23.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
real 0m0.200s
user 0m0.189s
sys 0m0.009s
././wave4main 4000 < /dev/null
expected stdout not matched by reality
--- wave4main.stdout 2014-07-08 20:57:14.000000000 +0100
+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17080.1 2014-07-13 13:43:23.000000000 +0100
@@ -1 +1 @@
-69923/1465
+69096/1465
make: *** [runtests] Error 1
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | NoFib benchmark suite |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"wave4main in nofib fails","status":"New","operating_system":"","component":"NoFib benchmark suite","related":[],"milestone":"7.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":["wave4main"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"\r\nCompiling HEAD with perf-llvm, (3.4.2) and running the nofib suite fails at the wave4main case. It is not clear to me whether wave4main should always produce the same output (and so the test fails because it does not do so) or whether the numbers generated depend on some feature of the build settings, or OS.\r\n\r\n\r\n{{{\r\nHC = /Users/xxx/Projects/ghc/inplace/bin/ghc-stage2\r\nHC_OPTS = -O2 -Rghc-timing -H32m -hisuf hi -cpp -fglasgow-exts -rtsopts\r\nRUNTEST_OPTS = -ghc-timing\r\n==nofib== wave4main: size of wave4main follows...\r\n__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\r\n4091904\t450560\t0\t4295947176\t4300489640\t1005443a8\r\n==nofib== wave4main: time to run wave4main follows...\r\n../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000; ../../../runstdtest/runstdtest ./wave4main -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -o1 wave4main.stdout -o1 wave4main.stdout2 -o1 wave4main.stdout3 -ghc-timing 4000;\r\n\r\nreal\t0m0.217s\r\nuser\t0m0.191s\r\nsys\t0m0.011s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16932.1\t2014-07-13 13:43:22.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.197s\r\nuser\t0m0.186s\r\nsys\t0m0.008s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest16961.1\t2014-07-13 13:43:22.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.201s\r\nuser\t0m0.189s\r\nsys\t0m0.009s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17011.1\t2014-07-13 13:43:22.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.201s\r\nuser\t0m0.190s\r\nsys\t0m0.008s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17051.1\t2014-07-13 13:43:23.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\n\r\nreal\t0m0.200s\r\nuser\t0m0.189s\r\nsys\t0m0.009s\r\n././wave4main 4000 < /dev/null\r\nexpected stdout not matched by reality\r\n--- wave4main.stdout\t2014-07-08 20:57:14.000000000 +0100\r\n+++ /var/folders/d9/94xh7l810mz3_skcsfh68khh0000gn/T//runtest17080.1\t2014-07-13 13:43:23.000000000 +0100\r\n@@ -1 +1 @@\r\n-69923/1465\r\n+69096/1465\r\nmake: *** [runtests] Error 1\r\n\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/8981ghc-pkg complains about missing haddock interface files2022-07-07T15:20:45Zthoughtpoliceghc-pkg complains about missing haddock interface filesAs Conal reported on the mailing list\[1\], `ghc-pkg check` on Mavericks allegedly returns:
```
bash-3.2$ ghc-pkg check
Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/uniplate-1.6.12/html/uniplate.ha...As Conal reported on the mailing list\[1\], `ghc-pkg check` on Mavericks allegedly returns:
```
bash-3.2$ ghc-pkg check
Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/uniplate-1.6.12/html/uniplate.haddock doesn't exist or isn't a file
Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/polyparse-1.9/html/polyparse.haddock doesn't exist or isn't a file
Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/ghc-syb-utils-0.2.1.2/html/ghc-syb-utils.haddock doesn't exist or isn't a file
Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/constraints-0.3.5/html/constraints.haddock doesn't exist or isn't a file
Warning: haddock-html: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/constraints-0.3.5/html doesn't exist or isn't a directory
Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/newtype-0.2/html/newtype.haddock doesn't exist or isn't a file
Warning: haddock-html: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/newtype-0.2/html doesn't exist or isn't a directory
```
It's not fatal, but makes the output much more annoying. I figured this would have been caught by validate or somesuch, but apparently not.
Marking for 7.8.2. I'm looking into this soon.
\[1\]http://www.haskell.org/pipermail/glasgow-haskell-users/2014-April/024846.html
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | Fuuzetsu |
| Operating system | MacOS X |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"ghc-pkg complains about missing haddock interface files","status":"New","operating_system":"MacOS X","component":"Compiler","related":[],"milestone":"7.8.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.1","keywords":["ghc-pkg"],"differentials":[],"test_case":"","architecture":"","cc":["Fuuzetsu"],"type":"Bug","description":"As Conal reported on the mailing list[1], `ghc-pkg check` on Mavericks allegedly returns:\r\n\r\n{{{\r\n\r\nbash-3.2$ ghc-pkg check\r\n Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/uniplate-1.6.12/html/uniplate.haddock doesn't exist or isn't a file\r\n Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/polyparse-1.9/html/polyparse.haddock doesn't exist or isn't a file\r\n Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/ghc-syb-utils-0.2.1.2/html/ghc-syb-utils.haddock doesn't exist or isn't a file\r\n Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/constraints-0.3.5/html/constraints.haddock doesn't exist or isn't a file\r\n Warning: haddock-html: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/constraints-0.3.5/html doesn't exist or isn't a directory\r\n Warning: haddock-interfaces: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/newtype-0.2/html/newtype.haddock doesn't exist or isn't a file\r\n Warning: haddock-html: /Users/conal/.cabal/share/doc/x86_64-osx-ghc-7.8.1/newtype-0.2/html doesn't exist or isn't a directory\r\n\r\n}}}\r\n\r\nIt's not fatal, but makes the output much more annoying. I figured this would have been caught by validate or somesuch, but apparently not.\r\n\r\nMarking for 7.8.2. I'm looking into this soon.\r\n\r\n[1]http://www.haskell.org/pipermail/glasgow-haskell-users/2014-April/024846.html","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/8862forkProcess does not play well with heap or time profiling2019-07-19T00:55:17ZbennofsforkProcess does not play well with heap or time profilingThis is similar to #4512. When doing heap or time profiling, the forked process and the parent process both write to the same `.hp` or `.prof` file. I think this also applies to program coverage using hpc (didn't test this).
I was able ...This is similar to #4512. When doing heap or time profiling, the forked process and the parent process both write to the same `.hp` or `.prof` file. I think this also applies to program coverage using hpc (didn't test this).
I was able to reproduce the bug with the attached source code, but some other people were not. Just run `space-profiling +RTS -h` and try to convert the generated heap profile using `hp2ps`, I get the following error message:
```
hp2ps: space-profiling.hp, line 186: integer must follow identifier
```
I attached the generated hp file.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.6.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":"forkProcess does not play well with heap or time profiling","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"This is similar to #4512. When doing heap or time profiling, the forked process and the parent process both write to the same `.hp` or `.prof` file. I think this also applies to program coverage using hpc (didn't test this). \r\n\r\nI was able to reproduce the bug with the attached source code, but some other people were not. Just run `space-profiling +RTS -h` and try to convert the generated heap profile using `hp2ps`, I get the following error message:\r\n\r\n{{{ \r\nhp2ps: space-profiling.hp, line 186: integer must follow identifier\r\n}}}\r\n\r\nI attached the generated hp file. ","type_of_failure":"OtherFailure","blocking":[]} -->Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/8695Arithmetic overflow from (minBound :: Int) `quot` (-1)2024-03-17T18:32:24ZrleslieArithmetic overflow from (minBound :: Int) `quot` (-1)According to the documentation for Data.Int, “All arithmetic is performed modulo 2!\^n, where n is the number of bits in the type.”
However, this promise is broken by the following exception:
```
Prelude> (minBound :: Int) `quot` (-1)
...According to the documentation for Data.Int, “All arithmetic is performed modulo 2!\^n, where n is the number of bits in the type.”
However, this promise is broken by the following exception:
```
Prelude> (minBound :: Int) `quot` (-1)
*** Exception: arithmetic overflow
```
(This also occurs with Int8, Int16, Int32, and Int64, and likewise for `div`.)
If all arithmetic is performed modulo 2!\^n, I would rather expect the above to evaluate to `minBound`, since after all `minBound * (-1) == minBound`. The fact that an exception is raised adds an unnecessary burden in pure code to ensure `quot` (or `div`) is never called with these specific arguments.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------------ |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | IncorrectResultAtRuntime |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/haskell2010 |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Arithmetic overflow from (minBound :: Int) `quot` (-1)","status":"New","operating_system":"","component":"libraries/haskell2010","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"According to the documentation for Data.Int, “All arithmetic is performed modulo 2!^n, where n is the number of bits in the type.”\r\n\r\nHowever, this promise is broken by the following exception:\r\n\r\n{{{\r\nPrelude> (minBound :: Int) `quot` (-1)\r\n*** Exception: arithmetic overflow\r\n}}}\r\n\r\n(This also occurs with Int8, Int16, Int32, and Int64, and likewise for `div`.)\r\n\r\nIf all arithmetic is performed modulo 2!^n, I would rather expect the above to evaluate to `minBound`, since after all `minBound * (-1) == minBound`. The fact that an exception is raised adds an unnecessary burden in pure code to ensure `quot` (or `div`) is never called with these specific arguments.","type_of_failure":"IncorrectResultAtRuntime","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/8362Filesystem related tests failed on solaris (SmartOS)2019-07-07T18:45:23ZlerouxFilesystem related tests failed on solaris (SmartOS)Getting filesystem (files/permissions) related test faiures on SmartOS (32bit).
```
$ uname -a
SunOS pkgx86 5.11 joyent_20130919T215407Z i86pc i386 i86pc Solaris
```
Unexpected failures: `TEST="openFile003 getPermissions001 processGrou...Getting filesystem (files/permissions) related test faiures on SmartOS (32bit).
```
$ uname -a
SunOS pkgx86 5.11 joyent_20130919T215407Z i86pc i386 i86pc Solaris
```
Unexpected failures: `TEST="openFile003 getPermissions001 processGroup002 user001 posix005"`
The testsuite output is attached.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | libraries (other) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Filesystem related tests failed on solaris (SmartOS)","status":"New","operating_system":"","component":"libraries (other)","related":[],"milestone":"7.8.3","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Getting filesystem (files/permissions) related test faiures on SmartOS (32bit).\r\n\r\n{{{\r\n$ uname -a\r\nSunOS pkgx86 5.11 joyent_20130919T215407Z i86pc i386 i86pc Solaris\r\n}}}\r\n\r\nUnexpected failures: `TEST=\"openFile003 getPermissions001 processGroup002 user001 posix005\"`\r\n\r\nThe testsuite output is attached.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/8293user001 spuriously fails if getGroupEntryForID correctly fails2019-07-07T18:45:41ZEdward Z. Yanguser001 spuriously fails if getGroupEntryForID correctly failsIn some cases, a user's current group ID can be a number for a non-existent group. While this usually indicates the system is misconfigured in some way, it can also occur inside chroots or other environments where the information in /etc...In some cases, a user's current group ID can be a number for a non-existent group. While this usually indicates the system is misconfigured in some way, it can also occur inside chroots or other environments where the information in /etc/groups is not to be considered reliable. Unfortunately, the user001 has no way of telling that the failure is proper, and fails the test anyway. We ought to do something more robust.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.7 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | lowest |
| Resolution | Unresolved |
| Component | libraries/unix |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"user001 spuriously fails if getGroupEntryForID correctly fails","status":"New","operating_system":"","component":"libraries/unix","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"In some cases, a user's current group ID can be a number for a non-existent group. While this usually indicates the system is misconfigured in some way, it can also occur inside chroots or other environments where the information in /etc/groups is not to be considered reliable. Unfortunately, the user001 has no way of telling that the failure is proper, and fails the test anyway. We ought to do something more robust.","type_of_failure":"OtherFailure","blocking":[]} -->Edward KmettEdward Kmetthttps://gitlab.haskell.org/ghc/ghc/-/issues/8285unexpected behavior with encodeFloat on large inputs2019-07-07T18:45:43ZCarter Schonwaldunexpected behavior with encodeFloat on large inputs```
> encodeFloat 1 1023
8.98846567431158e307 -- ok
> encodeFloat 1 1024
Infinity -- ok
> encodeFloat 1 (2^31 - 1)
Infinity -- ok
> encodeFloat 1 (2^31)
0.0 -- not ok
``````
> encodeFloat 1 1023
8.98846567431158e307 -- ok
> encodeFloat 1 1024
Infinity -- ok
> encodeFloat 1 (2^31 - 1)
Infinity -- ok
> encodeFloat 1 (2^31)
0.0 -- not ok
```8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/7997waitForProcess and getProcessExitCode are unsafe against asynchronous except...2019-07-07T18:47:07ZdfrankewaitForProcess and getProcessExitCode are unsafe against asynchronous exceptionsIn this description of the current behavior of *waitForProcess*, assume for simplicity the following:
1. The process being waited on has already terminated.
1. Neither *waitForProcess* nor *getProcessExitCode* has previously been called...In this description of the current behavior of *waitForProcess*, assume for simplicity the following:
1. The process being waited on has already terminated.
1. Neither *waitForProcess* nor *getProcessExitCode* has previously been called for this *ProcessHandle*.
1. *waitpid()* returns success on the first try; it does not get interrupted by a signal.
Under these assumptions, *waitForProcess* currently behaves as follows:
1. It is passed a *ProcessHandle* named *ph*. *ProcessHandle* is defined like so:
```
data ProcessHandle__ = OpenHandle PHANDLE | ClosedHandle ExitCode
newtype ProcessHandle = ProcessHandle (MVar ProcessHandle__)
```
1. It allocate a *CInt* using *alloca*; the pointer to it is named *pret*.
1. It passes *pret* to *c_waitForProcess*. *c_waitForProcess* makes a system call to *waitpid()*, and populates *pret* with the result.
1. *waitForProcess* peeks into *pret* and then mutates *ph*, changing it from an *OpenHandle* to a *ClosedHandle*.
There is already a comment in the source code mentioning that this approach is unsafe:
```
-- don't hold the MVar while we call c_waitForProcess...
-- (XXX but there's a small race window here during which another
-- thread could close the handle or call waitForProcess)
```
, which is correct. However, it is also unsafe against asynchronous exceptions, and would remain so even if the *MVar* were held during the *c_waitForProcess* call. If an asynchronous exception occurs in between steps 3 and 4, then the system will be left in a state in which the child process has been successfully waited on by the OS, but the *ProcessHandle* is still in an *OpenHandle* state and the exit code has been lost. A subsequent call to *waitForProcess* will result in *waitpid()* unexpectedly returning ECHILD, or worse, the OS will have recycled the child process's PID and *waitpid()* will wait on the wrong process.
*getProcessExitCode* has the same bug.
I propose fixing this by redefining *ProcessHandle* like so:
```
data ProcessHandle = ProcessHandle PHANDLE (Ptr CInt) (MVar (Ptr CInt))
```
, where the second argument maybe points to the process's return code, and the third argument contains a pointer to a boolean flag indicating whether the second argument points to something meaningful. Extend the signature of *c_waitForProcess* to take both pointers. Then, let *c_waitForProcess* provide the following contract. If called as *c_waitForProcess ph pret pflag*:
1. *\*pflag* is required to be false at the start of the call.
1. If and only if the call to *waitpid()* returns successfully, then *\*pflag* will be set to true and *\*pret* will be populated with the exit code.
Then, *waitForProcess* can behave as follows:
1. The entire routine is wrapped in *withMVar*. Asynchronous exceptions are allowed to occur.
1. If *\*pflag* is true, then construct an *ExitCode* from *\*pret* and return it.
1. Otherwise, call *c_waitForProcess* (with the same retry behavior as presently), and then construct and return an *ExitCode* after a successful return.
And *getProcessExitCode* can:
1. Mask exceptions.
1. *tryTakeMVar*. If the *MVar* is already held, unmask exceptions and return *Nothing*.
1. Peek at *\*pflag*.
1. Replace the *MVar*.
1. Unmask exceptions.
1. If *\*pflag* is true, then construct and return an *ExitCode* from *\*pret*.
1. Otherwise, return *Nothing*.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/process |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"waitForProcess and getProcessExitCode are unsafe against asynchronous exceptions","status":"New","operating_system":"","component":"libraries/process","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"In this description of the current behavior of ''waitForProcess'', assume for simplicity the following:\r\n\r\n1. The process being waited on has already terminated.\r\n\r\n2. Neither ''waitForProcess'' nor ''getProcessExitCode'' has previously been called for this ''ProcessHandle''.\r\n\r\n3. ''waitpid()'' returns success on the first try; it does not get interrupted by a signal.\r\n\r\nUnder these assumptions, ''waitForProcess'' currently behaves as follows:\r\n\r\n1. It is passed a ''ProcessHandle'' named ''ph''. ''ProcessHandle'' is defined like so:\r\n\r\n{{{\r\ndata ProcessHandle__ = OpenHandle PHANDLE | ClosedHandle ExitCode\r\nnewtype ProcessHandle = ProcessHandle (MVar ProcessHandle__)\r\n}}}\r\n\r\n2. It allocate a ''CInt'' using ''alloca''; the pointer to it is named ''pret''. \r\n\r\n3. It passes ''pret'' to ''c_waitForProcess''. ''c_waitForProcess'' makes a system call to ''waitpid()'', and populates ''pret'' with the result.\r\n\r\n4. ''waitForProcess'' peeks into ''pret'' and then mutates ''ph'', changing it from an ''OpenHandle'' to a ''ClosedHandle''.\r\n\r\nThere is already a comment in the source code mentioning that this approach is unsafe:\r\n\r\n\r\n{{{\r\n -- don't hold the MVar while we call c_waitForProcess...\r\n -- (XXX but there's a small race window here during which another\r\n -- thread could close the handle or call waitForProcess)\r\n}}}\r\n\r\n, which is correct. However, it is also unsafe against asynchronous exceptions, and would remain so even if the ''MVar'' were held during the ''c_waitForProcess'' call. If an asynchronous exception occurs in between steps 3 and 4, then the system will be left in a state in which the child process has been successfully waited on by the OS, but the ''ProcessHandle'' is still in an ''OpenHandle'' state and the exit code has been lost. A subsequent call to ''waitForProcess'' will result in ''waitpid()'' unexpectedly returning ECHILD, or worse, the OS will have recycled the child process's PID and ''waitpid()'' will wait on the wrong process.\r\n\r\n''getProcessExitCode'' has the same bug.\r\n\r\nI propose fixing this by redefining ''ProcessHandle'' like so:\r\n\r\n{{{\r\ndata ProcessHandle = ProcessHandle PHANDLE (Ptr CInt) (MVar (Ptr CInt))\r\n}}}\r\n\r\n, where the second argument maybe points to the process's return code, and the third argument contains a pointer to a boolean flag indicating whether the second argument points to something meaningful. Extend the signature of ''c_waitForProcess'' to take both pointers. Then, let ''c_waitForProcess'' provide the following contract. If called as ''c_waitForProcess ph pret pflag'':\r\n\r\n1. ''*pflag'' is required to be false at the start of the call.\r\n\r\n2. If and only if the call to ''waitpid()'' returns successfully, then ''*pflag'' will be set to true and ''*pret'' will be populated with the exit code.\r\n\r\nThen, ''waitForProcess'' can behave as follows:\r\n\r\n1. The entire routine is wrapped in ''withMVar''. Asynchronous exceptions are allowed to occur.\r\n\r\n2. If ''*pflag'' is true, then construct an ''ExitCode'' from ''*pret'' and return it.\r\n\r\n3. Otherwise, call ''c_waitForProcess'' (with the same retry behavior as presently), and then construct and return an ''ExitCode'' after a successful return.\r\n\r\nAnd ''getProcessExitCode'' can:\r\n\r\n1. Mask exceptions.\r\n\r\n2. ''tryTakeMVar''. If the ''MVar'' is already held, unmask exceptions and return ''Nothing''.\r\n\r\n3. Peek at ''*pflag''.\r\n\r\n4. Replace the ''MVar''.\r\n\r\n5. Unmask exceptions.\r\n\r\n6. If ''*pflag'' is true, then construct and return an ''ExitCode'' from ''*pret''.\r\n\r\n7. Otherwise, return ''Nothing''.","type_of_failure":"OtherFailure","blocking":[]} -->Michael Snoymanmichael@snoyman.comMichael Snoymanmichael@snoyman.comhttps://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/7398RULES don't apply to a newtype constructor2020-01-23T19:38:31ZshachafRULES don't apply to a newtype constructorFor some reason, RULES that involve a newtype constructor never seem to fire. The following program demonstrates the problem:
```
module Main where
newtype Foo a = Foo { unFoo :: a }
deriving Show
foo :: a -> Foo a
foo = Foo
{-# RU...For some reason, RULES that involve a newtype constructor never seem to fire. The following program demonstrates the problem:
```
module Main where
newtype Foo a = Foo { unFoo :: a }
deriving Show
foo :: a -> Foo a
foo = Foo
{-# RULES "rule Foo" forall v. Foo v = error "Foo" #-}
{-# RULES "rule foo" forall v. foo v = error "foo" #-}
main :: IO ()
main = do
print (Foo ())
print (foo ())
```
"rule foo" fires, but "rule Foo" doesn't. The program prints
```
Foo {unFoo = ()}
D: foo
```
Note that this doesn't seem to affect selectors, only constructors.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------------ |
| Version | 7.6.1 |
| Type | Bug |
| TypeOfFailure | IncorrectResultAtRuntime |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"RULES don't apply to a newtype constructor","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":"For some reason, RULES that involve a newtype constructor never seem to fire. The following program demonstrates the problem:\r\n\r\n{{{\r\nmodule Main where\r\n\r\nnewtype Foo a = Foo { unFoo :: a }\r\n deriving Show\r\n\r\nfoo :: a -> Foo a\r\nfoo = Foo\r\n\r\n{-# RULES \"rule Foo\" forall v. Foo v = error \"Foo\" #-}\r\n{-# RULES \"rule foo\" forall v. foo v = error \"foo\" #-}\r\n\r\nmain :: IO ()\r\nmain = do\r\n print (Foo ())\r\n print (foo ())\r\n}}}\r\n\r\n\"rule foo\" fires, but \"rule Foo\" doesn't. The program prints\r\n\r\n{{{\r\nFoo {unFoo = ()}\r\nD: foo\r\n}}}\r\n\r\nNote that this doesn't seem to affect selectors, only constructors.","type_of_failure":"IncorrectResultAtRuntime","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/7297LLVM incorrectly hoisting loads2019-07-07T18:50:28ZdtereiLLVM incorrectly hoisting loadstest 367_letnoescape fails under LLVM as a load of the !HpLim register is hoisted out of the loop. So yielding is never done.
What I am not sure about right now is the best way to fix. Loads in LLVM can be annotated in a few different w...test 367_letnoescape fails under LLVM as a load of the !HpLim register is hoisted out of the loop. So yielding is never done.
What I am not sure about right now is the best way to fix. Loads in LLVM can be annotated in a few different ways to fix this and not sure which one is the most 'correct'.
All the following work:
- mark the load as volatile. (seems to give nicest code as well)
- mark the load as atomic with either monotonic or seq_cst ordering.
- mark the load as both volatile and atomic.
This bug while only affecting a single test case seems very serious and potentially indicative of a large problem. How well are we communicating the load/store threaded semantics to LLVM?
And what semantics do we need to communicate? I think we are fine other than the STG registers...
So making a bug for now as I don't know yet the best way to proceed without dedicating some time to reading LLVM docs and probably talking to the LLVM devs as the docs on the memory model are fairly confusing.
e.g., Code in question:
Bad version (LBB0_1 loops forever as load hoisted out):
```
r1Uf_info: # @r1Uf_info
# BB#0: # %c1Vy
movq 144(%r13), %rax
decq %r14
.align 16, 0x90
.LBB0_1: # %tailrecurse
# =>This Inner Loop Header: Depth=1
incq %r14
testq %rax, %rax
jne .LBB0_1
# BB#2: # %c1VD
movq -8(%r13), %rax
movl $r1Uf_closure, %ebx
jmpq *%rax # TAILCALL
```
Code when marked with atomic (either monatonic or seq_cst) or both atomic and volatile:
```
r1Uf_info: # @r1Uf_info
# BB#0: # %c1Vy
decq %r14
.align 16, 0x90
.LBB0_1: # %tailrecurse
# =>This Inner Loop Header: Depth=1
incq %r14
movq 144(%r13), %rax
testq %rax, %rax
jne .LBB0_1
# BB#2: # %c1VD
movq -8(%r13), %rax
movl $r1Uf_closure, %ebx
jmpq *%rax # TAILCALL
```
Code when marked volatile:
```
r1Uf_info: # @r1Uf_info
# BB#0: # %c1Vy
decq %r14
.align 16, 0x90
.LBB0_1: # %tailrecurse
# =>This Inner Loop Header: Depth=1
incq %r14
cmpq $0, 144(%r13)
jne .LBB0_1
# BB#2: # %c1VD
movq -8(%r13), %rax
movl $r1Uf_closure, %ebx
jmpq *%rax # TAILCALL
```8.0.1dtereidtereihttps://gitlab.haskell.org/ghc/ghc/-/issues/7246Callstack depends on way (prof, profasm, profthreaded2019-07-07T18:50:42ZJoachim Breitnermail@joachim-breitner.deCallstack depends on way (prof, profasm, profthreadedConsider the attached test case. The expected output is the that of the ```prof``` way, while for ```profasm``` and ```profthreaded```, I get this result:
```
=====> callstack003(profthreaded) 19 of 21 [0, 1, 0]
cd . && '/home/jojo/doku...Consider the attached test case. The expected output is the that of the ```prof``` way, while for ```profasm``` and ```profthreaded```, I get this result:
```
=====> callstack003(profthreaded) 19 of 21 [0, 1, 0]
cd . && '/home/jojo/dokumente/Uni/info/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -o callstack003 callstack003.hs -O -prof -auto-all -threaded -fprof-auto-calls -fno-full-laziness -fno-state-hack >callstack003.comp.stderr 2>&1
cd . && ./callstack003 +RTS -p -RTS </dev/null >callstack003.run.stdout 2>callstack003.run.stderr
Actual stdout output differs from expected:
--- ./callstack003.stdout 2012-09-17 11:27:02.607458948 +0200
+++ ./callstack003.run.stdout 2012-09-17 12:20:33.988109494 +0200
@@ -1,8 +1,8 @@
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:15-17)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:22-24)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:15-17)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:22-24)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:15-17)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:22-24)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:15-17)","Main.f (callstack003.hs:7:11-36)"]
-["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.doTwice (callstack003.hs:10:22-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
+["Main.CAF (<entire-module>)","Main.main (callstack003.hs:9:8-21)","Main.doTwice (callstack003.hs:10:15-24)","Main.f (callstack003.hs:7:11-36)"]
*** unexpected failure for callstack003(profthreaded)
```
Not sure if this really hurts anyone, and the behavior of the call stack WRT recursive calls is anyways not quite perfect yet (see #7240), this makes adding good test cases a bit difficult.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Profiling |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Callstack depends on way (prof, profasm, profthreaded","status":"New","operating_system":"","component":"Profiling","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the attached test case. The expected output is the that of the ```prof``` way, while for ```profasm``` and ```profthreaded```, I get this result:\r\n\r\n{{{\r\n=====> callstack003(profthreaded) 19 of 21 [0, 1, 0]\r\ncd . && '/home/jojo/dokumente/Uni/info/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -o callstack003 callstack003.hs -O -prof -auto-all -threaded -fprof-auto-calls -fno-full-laziness -fno-state-hack >callstack003.comp.stderr 2>&1\r\ncd . && ./callstack003 +RTS -p -RTS </dev/null >callstack003.run.stdout 2>callstack003.run.stderr\r\nActual stdout output differs from expected:\r\n--- ./callstack003.stdout\t2012-09-17 11:27:02.607458948 +0200\r\n+++ ./callstack003.run.stdout\t2012-09-17 12:20:33.988109494 +0200\r\n@@ -1,8 +1,8 @@\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:15-17)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:22-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:15-17)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:22-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:15-17)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:22-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:15-17)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n-[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.doTwice (callstack003.hs:10:22-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n+[\"Main.CAF (<entire-module>)\",\"Main.main (callstack003.hs:9:8-21)\",\"Main.doTwice (callstack003.hs:10:15-24)\",\"Main.f (callstack003.hs:7:11-36)\"]\r\n*** unexpected failure for callstack003(profthreaded)\r\n}}}\r\n\r\nNot sure if this really hurts anyone, and the behavior of the call stack WRT recursive calls is anyways not quite perfect yet (see #7240), this makes adding good test cases a bit difficult.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1