GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2022-12-16T03:52:35Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/4243Make a proper options parser for the RTS2022-12-16T03:52:35ZIan Lynagh <igloo@earth.li>Make a proper options parser for the RTSThe RTS options parsing is getting increasingly crufty, and the new `rtsOptsEnabled` options have made it even worse. We should really have a proper options parser.
<details><summary>Trac metadata</summary>
| Trac field | V...The RTS options parsing is getting increasingly crufty, and the new `rtsOptsEnabled` options have made it even worse. We should really have a proper options parser.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.13 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Make a proper options parser for the RTS","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"7.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.13","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"The RTS options parsing is getting increasingly crufty, and the new `rtsOptsEnabled` options have made it even worse. We should really have a proper options parser.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1carlostomecarlostomehttps://gitlab.haskell.org/ghc/ghc/-/issues/3693Show stack traces2019-07-07T19:02:45ZjpetShow stack tracesDebugging stack overflows can be very difficult, because GHC gives very little information as to exactly what is overflowing. Showing a basic stack dump (on crash, or in the ghci debugger) would be enormously helpful.
(Entered after spe...Debugging stack overflows can be very difficult, because GHC gives very little information as to exactly what is overflowing. Showing a basic stack dump (on crash, or in the ghci debugger) would be enormously helpful.
(Entered after spending two days trying to determine the cause of a stack overflow, before discovering it was a GHC bug \[3677\], which would have been apparent immediately if I could have only seen a callstack.)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.4 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Show stack traces","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Debugging stack overflows can be very difficult, because GHC gives very little information as to exactly what is overflowing. Showing a basic stack dump (on crash, or in the ghci debugger) would be enormously helpful.\r\n\r\n(Entered after spending two days trying to determine the cause of a stack overflow, before discovering it was a GHC bug [3677], which would have been apparent immediately if I could have only seen a callstack.)\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1TarraschTarraschhttps://gitlab.haskell.org/ghc/ghc/-/issues/1466Stack check for AP_STACK2019-07-07T19:13:26ZSimon MarlowStack check for AP_STACKThis is a bug I uncovered in the interpreter, that I think is also present in the compiler.
When compiling code for a function or thunk, we aggregate the stack usage from case continuations up to the top of the function/thunk and perfor...This is a bug I uncovered in the interpreter, that I think is also present in the compiler.
When compiling code for a function or thunk, we aggregate the stack usage from case continuations up to the top of the function/thunk and perform a single stack check. This normally works fine: we know the maximum amount of stack that will be required in the evaluation of this function/thunk, and we check for it up front.
However, this goes wrong if the evaluation is suspended by an asynchronous exception: the stack is broken into chunks and stored in `AP_STACK` objects, which may later be resumed. On resumption, we might not have enough stack any more: the code might now be running on another stack entirely, even.
Our proposed solution is as follows:
- Continuations that require more than a certain amount of stack (say 4k)
do their own stack checks.
- an AP_STACK object records the amount of stack available at the time it
was suspended, if the amount is \<4k. On resumption of an AP_STACK, we
ensure that at least this amount of stack is available. (there's a
spare half-word field in AP_STACK that we can use for this).
The 4k limit is important: it puts a bound on the amount of stack growth due to evaluating an AP_STACK. Essentially the 4k limit is large enough that it almost never happens.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Stack check for AP_STACK","status":"New","operating_system":"Unknown","component":"Runtime System","related":[],"milestone":"6.8 branch","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"6.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Bug","description":"This is a bug I uncovered in the interpreter, that I think is also present in the compiler.\r\n\r\nWhen compiling code for a function or thunk, we aggregate the stack usage from case continuations up to the top of the function/thunk and perform a single stack check. This normally works fine: we know the maximum amount of stack that will be required in the evaluation of this function/thunk, and we check for it up front.\r\n\r\nHowever, this goes wrong if the evaluation is suspended by an asynchronous exception: the stack is broken into chunks and stored in `AP_STACK` objects, which may later be resumed. On resumption, we might not have enough stack any more: the code might now be running on another stack entirely, even.\r\n\r\nOur proposed solution is as follows:\r\n\r\n * Continuations that require more than a certain amount of stack (say 4k)\r\n do their own stack checks.\r\n\r\n * an AP_STACK object records the amount of stack available at the time it\r\n was suspended, if the amount is <4k. On resumption of an AP_STACK, we\r\n ensure that at least this amount of stack is available. (there's a\r\n spare half-word field in AP_STACK that we can use for this).\r\n\r\nThe 4k limit is important: it puts a bound on the amount of stack growth due to evaluating an AP_STACK. Essentially the 4k limit is large enough that it almost never happens.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/485AdjustorAsm.S doesn't build on AIX2019-07-07T19:17:47ZjgoerzenAdjustorAsm.S doesn't build on AIXOK, this is a weird one.
I'm building GHC 6.4.1 on AIX and using IBM's
assembler, since GNU binutils is known to have issues
on AIX.
When the build reached AdjustorAsm.S, I got:
```
imer.h -#include ProfHeap.h -#include LdvProfile.h
-...OK, this is a weird one.
I'm building GHC 6.4.1 on AIX and using IBM's
assembler, since GNU binutils is known to have issues
on AIX.
When the build reached AdjustorAsm.S, I got:
```
imer.h -#include ProfHeap.h -#include LdvProfile.h
-#include Profiling.h -#inclu
de Apply.h -fvia-C -dcmm-lint -c AdjustorAsm.S -o
AdjustorAsm.o
Assembler:
/tmp//ccq7dlbU.s: line 15: 1252-016 The specified
opcode or pseudo-op is not val
id.
Use supported instructions or pseudo-ops only.
/tmp//ccq7dlbU.s: line 48: 1252-149 Instruction subf is
not implemented in the c
urrent assembly mode COM.
/tmp//ccq7dlbU.s: line 52: 1252-142 Syntax error.
/tmp//ccq7dlbU.s: line 53: 1252-142 Syntax error.
/tmp//ccq7dlbU.s: line 58: 1252-142 Syntax error.
/tmp//ccq7dlbU.s: line 59: 1252-142 Syntax error.
make[2]: *** [AdjustorAsm.o] Error 1
```
After some research, I added -opta -Wa,-mppc, which
reduced the errors to:
```
/tmp//ccA1yNhC.s: line 15: 1252-016 The specified
opcode or pseudo-op is not val
id.
Use supported instructions or pseudo-ops only.
/tmp//ccA1yNhC.s: line 52: 1252-142 Syntax error.
/tmp//ccA1yNhC.s: line 53: 1252-142 Syntax error.
/tmp//ccA1yNhC.s: line 58: 1252-142 Syntax error.
/tmp//ccA1yNhC.s: line 59: 1252-142 Syntax error.
```
I examined the temp files and found that line 15
contains only the word ".text".
I was finally able to work around the problem by adding
-opta -save-temps to the command line, then using GNU
as like so:
as mppc -I. AdjustorAsm.s -o AdjustorAsm.o
I then copied the resulting .o file to the thr, p,
debug, etc. .o files. The build was then able to complete.8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9579Runtime suggests using +RTS when that's not possible2019-07-07T18:39:56ZgintasRuntime suggests using +RTS when that's not possibleI just ran into a stack overflow in an application, and GHC told me:
Stack space overflow: current size 8388608 bytes.
Use \`+RTS -Ksize -RTS' to increase it.
I tried to specify +RTS and got an error saying "Most RTS options are disabl...I just ran into a stack overflow in an application, and GHC told me:
Stack space overflow: current size 8388608 bytes.
Use \`+RTS -Ksize -RTS' to increase it.
I tried to specify +RTS and got an error saying "Most RTS options are disabled. Link with -rtsopts to enable them."
The runtime should not suggest using +RTS when that is not possible.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | low |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | simonmar |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Runtime suggests using +RTS when that's not possible","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonmar"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["simonmar"],"type":"Bug","description":"I just ran into a stack overflow in an application, and GHC told me:\r\n\r\nStack space overflow: current size 8388608 bytes.\r\nUse `+RTS -Ksize -RTS' to increase it.\r\n\r\nI tried to specify +RTS and got an error saying \"Most RTS options are disabled. Link with -rtsopts to enable them.\"\r\n\r\nThe runtime should not suggest using +RTS when that is not possible.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/9261-S prints incorrect number of bound tasks2019-07-07T18:41:09Zedsko@edsko.net-S prints incorrect number of bound tasksIn `rts/Stats.c` we have:
```
statsPrintf(" TASKS: %d (%d bound, %d peak workers (%d total), using -N%d)\n",
taskCount, taskCount - workerCount,
peakWorkerCount, workerCount,
...In `rts/Stats.c` we have:
```
statsPrintf(" TASKS: %d (%d bound, %d peak workers (%d total), using -N%d)\n",
taskCount, taskCount - workerCount,
peakWorkerCount, workerCount,
n_capabilities);
```
but I think `taskCount - workerCount` must be wrong, because `taskCount` is the _current_ number of tasks, while `workerAcount` is the _total_ number of workers (accumulating). I think it should be:
```
statsPrintf(" TASKS: %d (%d bound, %d peak workers (%d total), using -N%d)\n",
taskCount, taskCount - currentWorkerCount,
peakWorkerCount, workerCount,
n_capabilities);
```8.0.1Thomas MiedemaThomas Miedemahttps://gitlab.haskell.org/ghc/ghc/-/issues/8303defer StackOverflow exceptions (rather than dropping them) when exceptions ar...2019-07-07T18:45:39Zrwbartondefer StackOverflow exceptions (rather than dropping them) when exceptions are maskedSee http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/ for a very simple program (`main'`) that accidentally evades the stack size limit, running to completion even though it has allocated hundreds of megabyte...See http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/ for a very simple program (`main'`) that accidentally evades the stack size limit, running to completion even though it has allocated hundreds of megabytes of stack chunks, and [my comment](http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/cc32ec4) for an explanation of this behavior.
ryani suggested that when a thread exceeds its stack limit but it is currently blocking exceptions, the RTS shouldn't simply drop the `StackOverflow` exception, but rather deliver it when the `mask` operation completes. That sounds sensible to me and it would give a nice guarantee that when any individual `mask` operation uses a small amount of stack, the stack size limit is approximately enforced.
(I know that the default stack size limit may go away or essentially go away, but it can still be nice when developing to use a small stack size limit, so that one's system isn't run into the ground by infinite recursion quickly gobbling up tons of memory.)
<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 | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"defer StackOverflow exceptions (rather than dropping them) when exceptions are masked","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"See http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/ for a very simple program (`main'`) that accidentally evades the stack size limit, running to completion even though it has allocated hundreds of megabytes of stack chunks, and [http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/cc32ec4 my comment] for an explanation of this behavior.\r\n\r\nryani suggested that when a thread exceeds its stack limit but it is currently blocking exceptions, the RTS shouldn't simply drop the `StackOverflow` exception, but rather deliver it when the `mask` operation completes. That sounds sensible to me and it would give a nice guarantee that when any individual `mask` operation uses a small amount of stack, the stack size limit is approximately enforced.\r\n\r\n(I know that the default stack size limit may go away or essentially go away, but it can still be nice when developing to use a small stack size limit, so that one's system isn't run into the ground by infinite recursion quickly gobbling up tons of memory.)","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1thoughtpolicethoughtpolicehttps://gitlab.haskell.org/ghc/ghc/-/issues/5219need a version of hs_init that returns an error code for command-line errors2019-07-07T18:56:22ZSimon Marlowneed a version of hs_init that returns an error code for command-line errorsThis ticket is extracted from Roman's comment in #4464:
`hs_init` simply aborts if it doesn't like the RTS arguments which is quite unhelpful for dynamic libraries. I took me a day to find out that an application crash was caused by a f...This ticket is extracted from Roman's comment in #4464:
`hs_init` simply aborts if it doesn't like the RTS arguments which is quite unhelpful for dynamic libraries. I took me a day to find out that an application crash was caused by a failing hs_init (because of the -rtsopts problem). I would like to add a check for this to our code but there doesn't seem to be a way to do this. It would be much nicer if hs_init returned a failure/success code, at least for dynamic libraries.
To which I responded:
If hs_init needs to return an error condition rather than aborting, then we need to define a new API for that, and fix setupRtsFlags. I don't think we need to do this for every case of stg_exit and certainly not for barf: these are all internal error conditions and we have no sensible way to recover.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.0.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | rl |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"need a version of hs_init that returns an error code for command-line errors","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"7.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["rl"],"type":"FeatureRequest","description":"This ticket is extracted from Roman's comment in #4464:\r\n\r\n`hs_init` simply aborts if it doesn't like the RTS arguments which is quite unhelpful for dynamic libraries. I took me a day to find out that an application crash was caused by a failing hs_init (because of the -rtsopts problem). I would like to add a check for this to our code but there doesn't seem to be a way to do this. It would be much nicer if hs_init returned a failure/success code, at least for dynamic libraries. \r\n\r\nTo which I responded:\r\n\r\nIf hs_init needs to return an error condition rather than aborting, then we need to define a new API for that, and fix setupRtsFlags. I don't think we need to do this for every case of stg_exit and certainly not for barf: these are all internal error conditions and we have no sensible way to recover.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/5197Support static linker semantics for archives and weak symbols2021-11-11T17:51:13ZduncanSupport static linker semantics for archives and weak symbolsWhile looking at #5004, I had a go at getting the GHCi linker to load the LLVM libs, as in making this work: `ghci -package llvm`.
This involves loading a whole bunch of LLVM\*.a files and linking them against the C and C++ standard lib...While looking at #5004, I had a go at getting the GHCi linker to load the LLVM libs, as in making this work: `ghci -package llvm`.
This involves loading a whole bunch of LLVM\*.a files and linking them against the C and C++ standard libs. This in turn requires a few more features in the GHCi linker:
- support for weak symbols
- search archives only on demand
- support .oS files in archives
The last is trivial.
The first is not so hard to do. When the linker finds a definition of a weak symbol, if there's already a symbol with that name in the symbol table then we just ignore the new one. When resolving symbols if we find an unresolved weak symbol we just give it the value zero. Doing this is enough to load .e.g libstdc++.a and libc.a (rather than libc.so).
The next part is a bit more work. When you give system static linker some .a files, it only uses them to provide definitions for unresolved symbols in the main target. In particular it is fine for two .a files to provide definitions of the same symbol because the linker just looks for the first. (This is in contrast to duplicate symbols in the main .o input files). On linux, both libm and libc define some of the same symbols, such as `__isinf`.
Similarly, there is a problem that the GHCi linker predefines the `atexit` symbol, but that is also defined by `libc.a`.
So for the GHCi linker to load both libm and libc then it has to follow the standard semantics for linking archives. Currently it treats an archive as a request to link all the .o files in that archive.
Probably it is not sensible to go as far as implementing the full standard static linking semantics in the GHCi linker. It's of somewhat questionable value since we mainly need it for linking Haskell code, not C/C++ code.
Nevertheless, if we do need this, then the attached Linker.c has a partial implementation. It does the weak symbols and `.oS` files in archives.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.0.3 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | GHCi |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Support static linker semantics for archives and weak symbols","status":"New","operating_system":"","component":"GHCi","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"While looking at #5004, I had a go at getting the GHCi linker to load the LLVM libs, as in making this work: `ghci -package llvm`.\r\n\r\nThis involves loading a whole bunch of LLVM*.a files and linking them against the C and C++ standard libs. This in turn requires a few more features in the GHCi linker:\r\n\r\n * support for weak symbols\r\n * search archives only on demand\r\n * support .oS files in archives\r\n\r\nThe last is trivial.\r\n\r\nThe first is not so hard to do. When the linker finds a definition of a weak symbol, if there's already a symbol with that name in the symbol table then we just ignore the new one. When resolving symbols if we find an unresolved weak symbol we just give it the value zero. Doing this is enough to load .e.g libstdc++.a and libc.a (rather than libc.so).\r\n\r\nThe next part is a bit more work. When you give system static linker some .a files, it only uses them to provide definitions for unresolved symbols in the main target. In particular it is fine for two .a files to provide definitions of the same symbol because the linker just looks for the first. (This is in contrast to duplicate symbols in the main .o input files). On linux, both libm and libc define some of the same symbols, such as `__isinf`.\r\n\r\nSimilarly, there is a problem that the GHCi linker predefines the `atexit` symbol, but that is also defined by `libc.a`.\r\n\r\nSo for the GHCi linker to load both libm and libc then it has to follow the standard semantics for linking archives. Currently it treats an archive as a request to link all the .o files in that archive.\r\n\r\nProbably it is not sensible to go as far as implementing the full standard static linking semantics in the GHCi linker. It's of somewhat questionable value since we mainly need it for linking Haskell code, not C/C++ code.\r\n\r\nNevertheless, if we do need this, then the attached Linker.c has a partial implementation. It does the weak symbols and `.oS` files in archives.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4913Make event tracing conditional on an RTS flag only2019-07-07T18:57:57ZtibbeMake event tracing conditional on an RTS flag onlyThe current event tracing mechanism is enabled at link time by linking in one of two different versions of a C function, one being a no-op function. We could allow users to enable/disable tracing using a RTS flag instead, making event lo...The current event tracing mechanism is enabled at link time by linking in one of two different versions of a C function, one being a no-op function. We could allow users to enable/disable tracing using a RTS flag instead, making event logging more convenient to use. At the same time we would introduce tracing levels.
Design:
Add a static memory location where the current tracing level is stored:
```
uint tracelevel = 0;
```
Modify `GHC.Exts.traceEvent` to read
```
foreign import ccall unsafe "&tracelevel" :: Ptr Word
traceEvent :: String -> IO ()
traceEvent msg =
if unsafePerformIO (peek tracelevel) > 0
then do
withCString msg $ \(Ptr p) -> IO $ \s ->
case traceEvent# p s of s' -> (# s', () #)
else return ()
```
and (optionally) add some more functions that log at different trace levels.
This should be no slower than the current system. With inlining this should result in a load and a branch at the call site. The load should be cheap as the value is likely to be in cache (as it never changes). The branch should be easy to predict as it's always the same. With some cooperation from the code generator we could make sure that the branch is always cheap.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 7.0.1 |
| Type | FeatureRequest |
| 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 event tracing conditional on an RTS flag only","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The current event tracing mechanism is enabled at link time by linking in one of two different versions of a C function, one being a no-op function. We could allow users to enable/disable tracing using a RTS flag instead, making event logging more convenient to use. At the same time we would introduce tracing levels.\r\n\r\nDesign:\r\n\r\nAdd a static memory location where the current tracing level is stored:\r\n\r\n{{{\r\nuint tracelevel = 0;\r\n}}}\r\n\r\nModify `GHC.Exts.traceEvent` to read\r\n\r\n{{{\r\nforeign import ccall unsafe \"&tracelevel\" :: Ptr Word\r\n\r\ntraceEvent :: String -> IO ()\r\ntraceEvent msg =\r\n if unsafePerformIO (peek tracelevel) > 0\r\n then do\r\n withCString msg $ \\(Ptr p) -> IO $ \\s ->\r\n case traceEvent# p s of s' -> (# s', () #)\r\n else return ()\r\n}}}\r\n\r\nand (optionally) add some more functions that log at different trace levels.\r\n\r\nThis should be no slower than the current system. With inlining this should result in a load and a branch at the call site. The load should be cheap as the value is likely to be in cache (as it never changes). The branch should be easy to predict as it's always the same. With some cooperation from the code generator we could make sure that the branch is always cheap.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4824Windows: Dynamic linking doesn't work out-of-the-box2021-04-21T21:11:06ZOrphiWindows: Dynamic linking doesn't work out-of-the-boxI did this:
1. Download and install GHC 7.0.1
1. Compile `HelloWorld.hs` with the "-dynamic" flag.
1. Run the resulting binary.
When I run the program, I get a dialog box telling me that the program can't find the RTS DLL.
If I move t...I did this:
1. Download and install GHC 7.0.1
1. Compile `HelloWorld.hs` with the "-dynamic" flag.
1. Run the resulting binary.
When I run the program, I get a dialog box telling me that the program can't find the RTS DLL.
If I move the necessary DLLs to somewhere in the search path, the binary runs just fine. The bug is that the Windows installer for GHC does not do this itself.
(I've classified this bug as "runtime system", but really it's an installer bug, not an RTS bug.)
Related to this are two complications:
1. The documentation fails to describe how GHC tries to find dynamic libraries on Windows. (Section 4.12.4 of the User Guide only explains how this is done for Unix and Mac OS.)
1. The DLLs are scattered all over the place. If they were all in one folder, I could just add that to the search path. But they aren't.8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/4520startup code on Windows should use SetDllDirectory("")2019-07-07T18:58:37Zduncanstartup code on Windows should use SetDllDirectory("")See [Raymond's blog](http://blogs.msdn.com/b/oldnewthing/archive/2010/11/10/10088566.aspx) about (un)safe dll loading. He points to a [support article](http://support.microsoft.com/kb/2389418) which recommends that new programs use `SetD...See [Raymond's blog](http://blogs.msdn.com/b/oldnewthing/archive/2010/11/10/10088566.aspx) about (un)safe dll loading. He points to a [support article](http://support.microsoft.com/kb/2389418) which recommends that new programs use `SetDllDirectory("")` to prevent the problem (it's not the default because that'd break old programs).
In the GHC context, this could go in the startup code for standalone executables. It is a process-scope property so changing it is not appropriate for DLL startup.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 7.0.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown/Multiple |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"startup code on Windows should use SetDllDirectory(\"\")","status":"New","operating_system":"Unknown/Multiple","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"See [http://blogs.msdn.com/b/oldnewthing/archive/2010/11/10/10088566.aspx Raymond's blog] about (un)safe dll loading. He points to a [http://support.microsoft.com/kb/2389418 support article] which recommends that new programs use `SetDllDirectory(\"\")` to prevent the problem (it's not the default because that'd break old programs).\r\n\r\nIn the GHC context, this could go in the startup code for standalone executables. It is a process-scope property so changing it is not appropriate for DLL startup.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3946Better diagnostic when entering a GC'd CAF2019-11-14T10:52:47ZSimon MarlowBetter diagnostic when entering a GC'd CAFCurrently a GC'd CAF contains a dangling pointer, so entering it will result in a segfault or some other random failure. It would be better to give a useful diagnostic in this case (see #3900), not only to detect when `keepCAFs` is neede...Currently a GC'd CAF contains a dangling pointer, so entering it will result in a segfault or some other random failure. It would be better to give a useful diagnostic in this case (see #3900), not only to detect when `keepCAFs` is needed, but also to help find bugs in the code generator's SRT table generation and GC bugs.
Here is one way it could be done. We use the static link field of a static closure to indicate whether the closure is live or not:
- link field is non-zero if and only if the closure was reachable at the last GC, otherwise it is zero
if an `IND_STATIC` closure has a zero link field, then we know for sure that the closure pointed to by the `IND_STATIC` is invalid and entering the `IND_STATIC` should give a helpful error message.
To implement this:
- on entering a CAF, set the link field to 1.
- at the beginning of (major) GC, set all the link fields for static closures that were reachable during the last major GC to zero
- during GC, link fields for reachable static closures get set to non-zero as they are linked onto first the static_objects list and then the scavenged_static_objects list.
One problem is that this scheme means traversing and writing to all the static closures at the beginning of GC, when some of them may be dead, and many will not be in the cache. The current way of doing this at the end of GC is better from a cache perspective. To refine the above approach, we could do the extra zeroing phase at the beginning of GC for `IND_STATIC` closures only, and the others would get the current treatment.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.12.1 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Better diagnostic when entering a GC'd CAF","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"7.0.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Currently a GC'd CAF contains a dangling pointer, so entering it will result in a segfault or some other random failure. It would be better to give a useful diagnostic in this case (see #3900), not only to detect when `keepCAFs` is needed, but also to help find bugs in the code generator's SRT table generation and GC bugs.\r\n\r\nHere is one way it could be done. We use the static link field of a static closure to indicate whether the closure is live or not:\r\n\r\n * link field is non-zero if and only if the closure was reachable at the last GC, otherwise it is zero\r\n\r\nif an `IND_STATIC` closure has a zero link field, then we know for sure that the closure pointed to by the `IND_STATIC` is invalid and entering the `IND_STATIC` should give a helpful error message.\r\n\r\nTo implement this:\r\n\r\n * on entering a CAF, set the link field to 1.\r\n * at the beginning of (major) GC, set all the link fields for static closures that were reachable during the last major GC to zero\r\n * during GC, link fields for reachable static closures get set to non-zero as they are linked onto first the static_objects list and then the scavenged_static_objects list.\r\n\r\nOne problem is that this scheme means traversing and writing to all the static closures at the beginning of GC, when some of them may be dead, and many will not be in the cache. The current way of doing this at the end of GC is better from a cache perspective. To refine the above approach, we could do the extra zeroing phase at the beginning of GC for `IND_STATIC` closures only, and the others would get the current treatment.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3937Cannot killThread in listen/accept on Windows threaded runtime2020-07-27T06:46:51ZguestCannot killThread in listen/accept on Windows threaded runtimeThe killThread is not able to kill threads accepting socket connections on Windows.
Run attached file either in GHCi:
```
runghc.exe ListenOn.hs
```
or compile threaded:
```
ghc --make -threaded ListenOn.hs
```
Resulting binary hang...The killThread is not able to kill threads accepting socket connections on Windows.
Run attached file either in GHCi:
```
runghc.exe ListenOn.hs
```
or compile threaded:
```
ghc --make -threaded ListenOn.hs
```
Resulting binary hangs.
Expected behavior: should finish without problems.
Non-threaded runtime produces expected behavior. Seems to work correctly on Linux.
Affected: ghc-6.10.4 and ghc-6.12.1.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.12.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":"Cannot killThread in listen/accept on Windows threaded runtime","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The killThread is not able to kill threads accepting socket connections on Windows.\r\n\r\nRun attached file either in GHCi:\r\n\r\n{{{\r\nrunghc.exe ListenOn.hs\r\n}}}\r\n\r\n\r\nor compile threaded:\r\n\r\n\r\n{{{\r\nghc --make -threaded ListenOn.hs\r\n}}}\r\n\r\n\r\nResulting binary hangs.\r\n\r\nExpected behavior: should finish without problems.\r\n\r\nNon-threaded runtime produces expected behavior. Seems to work correctly on Linux.\r\n\r\nAffected: ghc-6.10.4 and ghc-6.12.1.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3869RTS GC Statistics from -S should be logged via the eventlog system2021-03-05T21:34:44ZcjsRTS GC Statistics from -S should be logged via the eventlog systemThe -Sfilename option to the RTS gives useful GC statistics, but it's hard to correlate these with other events, particularly to see if GC is interrupting critical sections in mutator threads. If the same information were instead logged ...The -Sfilename option to the RTS gives useful GC statistics, but it's hard to correlate these with other events, particularly to see if GC is interrupting critical sections in mutator threads. If the same information were instead logged via the eventlog system (perhaps enabled via a "-lg" option) one could get more insight into the garbage generation and collection behaviour of one's program.
Note that it's probably not necessary also to store the information given at the end of the run with both "-s" and "-S", though it may be interesting to contemplate moving this sort of thing into the eventlog file as well.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.12.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"RTS GC Statistics from -S should be logged via the eventlog system","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.12.1","keywords":["collection,","garbage","gc,","statistics"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The -Sfilename option to the RTS gives useful GC statistics, but it's hard to correlate these with other events, particularly to see if GC is interrupting critical sections in mutator threads. If the same information were instead logged via the eventlog system (perhaps enabled via a \"-lg\" option) one could get more insight into the garbage generation and collection behaviour of one's program.\r\n\r\nNote that it's probably not necessary also to store the information given at the end of the run with both \"-s\" and \"-S\", though it may be interesting to contemplate moving this sort of thing into the eventlog file as well.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3462New codegen: allocate large objects using allocateLocal()2019-07-07T19:03:45ZSimon MarlowNew codegen: allocate large objects using allocateLocal()See #3424.
In the new code generator, we should allocate large objects (larger than F \* block size, for some suitable fraction F) using the RTS `allocateLocal()` API rather than from the nursery. It works to allocate them from the nurs...See #3424.
In the new code generator, we should allocate large objects (larger than F \* block size, for some suitable fraction F) using the RTS `allocateLocal()` API rather than from the nursery. It works to allocate them from the nursery -- this is what GHC 6.12 does after the fix in #3424 -- but then they will not be treated as large objects and will be copied during GC. Also, the allocation is likely to fail, requiring a trip through the RTS to put a large enough block in the nursery to satisfy the allocation.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 6.11 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"New codegen: allocate large objects using allocateLocal()","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"6.14.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.11","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"See #3424.\r\n\r\nIn the new code generator, we should allocate large objects (larger than F * block size, for some suitable fraction F) using the RTS `allocateLocal()` API rather than from the nursery. It works to allocate them from the nursery -- this is what GHC 6.12 does after the fix in #3424 -- but then they will not be treated as large objects and will be copied during GC. Also, the allocation is likely to fail, requiring a trip through the RTS to put a large enough block in the nursery to satisfy the allocation.\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Simon MarlowSimon Marlowhttps://gitlab.haskell.org/ghc/ghc/-/issues/3251split rts headers into public and private2019-07-07T19:04:44Zduncansplit rts headers into public and privateC code calling into the rts, eg to initialise it, uses header files like `HsFFI.h` or `RtsAPI.h`. However these header files that describe the public API of the rts are installed in `$libdir/ghc-x.y/include` where as the standard locatio...C code calling into the rts, eg to initialise it, uses header files like `HsFFI.h` or `RtsAPI.h`. However these header files that describe the public API of the rts are installed in `$libdir/ghc-x.y/include` where as the standard location for public header files should be `$prefix/include/ghc-x.y`.
The private header files that are only used by `.hc` files when compiling `-fvia-C` should remain where they are. So this would involve identifying which headers are public and which are private.
Once we have a set of public header files it might be nice to provide a `pkg-config` .pc file to make it easy for C programs to locate the header files and libraries. Eg it should be possible to compile and link a C program that uses the RTS public API with just:
```
gcc -o main main.c `pkg-config --cflags --libs ghc-rts-6.12.1`
```
and this would supply the flags like
```
-I/usr/include/ghc-6.12.1 -lHSrts -L/usr/lib/ghc-6.12.1
```
Note that `pkg-config` supports both shared and static libs (ie allows specifying the extra private deps of a static lib, eg `-lm -ldl` etc).
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"split rts headers into public and private","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"C code calling into the rts, eg to initialise it, uses header files like `HsFFI.h` or `RtsAPI.h`. However these header files that describe the public API of the rts are installed in `$libdir/ghc-x.y/include` where as the standard location for public header files should be `$prefix/include/ghc-x.y`.\r\n\r\nThe private header files that are only used by `.hc` files when compiling `-fvia-C` should remain where they are. So this would involve identifying which headers are public and which are private.\r\n\r\nOnce we have a set of public header files it might be nice to provide a `pkg-config` .pc file to make it easy for C programs to locate the header files and libraries. Eg it should be possible to compile and link a C program that uses the RTS public API with just:\r\n{{{\r\ngcc -o main main.c `pkg-config --cflags --libs ghc-rts-6.12.1`\r\n}}}\r\nand this would supply the flags like\r\n{{{\r\n-I/usr/include/ghc-6.12.1 -lHSrts -L/usr/lib/ghc-6.12.1\r\n}}}\r\nNote that `pkg-config` supports both shared and static libs (ie allows specifying the extra private deps of a static lib, eg `-lm -ldl` etc).","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3107Over-eager GC when blocked on a signal in the non-threaded runtime2019-07-07T19:05:21ZawickOver-eager GC when blocked on a signal in the non-threaded runtimeRight now, in the non-threaded runtime, if you have the situation where all the threads are blocked on MVars, the deadlock detection / avoidance code runs a GC. This is fine, generally, but if they're blocked on MVars held by signal hand...Right now, in the non-threaded runtime, if you have the situation where all the threads are blocked on MVars, the deadlock detection / avoidance code runs a GC. This is fine, generally, but if they're blocked on MVars held by signal handlers, it has a profoundly bad effect on performance. In short, the runtime starts collection (blocking signals?), and we're stuck waiting for it to finish before handling signals. Or, if the signal doesn't come in, we sit waiting in a loop, garbage collecting.
It would be nice if the runtime either didn't trigger collection if signal handlers are in place, or, at the very least, held off on doing so for a nontrivial period of time.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | dons |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Over-eager GC when blocked on a signal in the non-threaded runtime","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["dons"],"type":"Bug","description":"Right now, in the non-threaded runtime, if you have the situation where all the threads are blocked on MVars, the deadlock detection / avoidance code runs a GC. This is fine, generally, but if they're blocked on MVars held by signal handlers, it has a profoundly bad effect on performance. In short, the runtime starts collection (blocking signals?), and we're stuck waiting for it to finish before handling signals. Or, if the signal doesn't come in, we sit waiting in a loop, garbage collecting.\r\n\r\nIt would be nice if the runtime either didn't trigger collection if signal handlers are in place, or, at the very least, held off on doing so for a nontrivial period of time.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/3061GHC's GC default heap growth strategy is not as good as other runtimes2019-07-07T19:05:35ZdonsGHC's GC default heap growth strategy is not as good as other runtimesThis is a GC performance ticket. The benchmark is the binary-trees benchmark, and the issue is whether or not GHC's ability to grow the heap without a heap check is comparably worse than other similar language runtimes.
Looking at the b...This is a GC performance ticket. The benchmark is the binary-trees benchmark, and the issue is whether or not GHC's ability to grow the heap without a heap check is comparably worse than other similar language runtimes.
Looking at the binary-trees benchmark, we see that GHC does very well on a parallel system, when we give a GC hint to the size.
E.g. the attached binary-trees program is very very competitive:
Compile with:
```
ghc -O2 -fasm --make -threaded A.hs
```
Run with:
```
$ /A 20 +RTS -N4 -H340M
```
And we get:
```
$ time ./A +RTS -N4 -H340M -RTS 20
stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1
./A +RTS -N4 -H340M -RTS 20 17.08s user 0.30s system 315% cpu 5.511 total
```
However, without that GC hint performance deteriorates dramatically,
```
$ time ./A +RTS -N4 -RTS 20
stretch tree of depth 21 check: -1
2097152 trees of depth 4 check: -2097152
524288 trees of depth 6 check: -524288
131072 trees of depth 8 check: -131072
32768 trees of depth 10 check: -32768
8192 trees of depth 12 check: -8192
2048 trees of depth 14 check: -2048
512 trees of depth 16 check: -512
128 trees of depth 18 check: -128
32 trees of depth 20 check: -32
long lived tree of depth 20 check: -1
./A +RTS -N4 -RTS 20 33.83s user 0.42s system 136% cpu 25.033 total
```
So 5x slow down.
Could the GC heap growth algorithm be tuned? Other language runtimes, that are slower than Haskell's on this benchmark when our GC hint is in play, don't seem to suffer as badly without the hint:
> http://shootout.alioth.debian.org/u64q/benchmark.php?test=binarytrees&lang=all
See e.g. Erlang. So: is there a better growth algorithm?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.10.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":"GHC's GC default heap growth strategy is not as good as other runtimes","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":["GC","performance,"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This is a GC performance ticket. The benchmark is the binary-trees benchmark, and the issue is whether or not GHC's ability to grow the heap without a heap check is comparably worse than other similar language runtimes. \r\n\r\nLooking at the binary-trees benchmark, we see that GHC does very well on a parallel system, when we give a GC hint to the size.\r\n\r\nE.g. the attached binary-trees program is very very competitive:\r\n\r\nCompile with:\r\n\r\n{{{\r\n ghc -O2 -fasm --make -threaded A.hs \r\n}}}\r\n\r\nRun with:\r\n\r\n{{{\r\n $ /A 20 +RTS -N4 -H340M\r\n}}}\r\n\r\nAnd we get:\r\n\r\n{{{\r\n $ time ./A +RTS -N4 -H340M -RTS 20 \r\nstretch tree of depth 21\t check: -1\r\n2097152\t trees of depth 4\t check: -2097152\r\n524288\t trees of depth 6\t check: -524288\r\n131072\t trees of depth 8\t check: -131072\r\n32768\t trees of depth 10\t check: -32768\r\n8192\t trees of depth 12\t check: -8192\r\n2048\t trees of depth 14\t check: -2048\r\n512\t trees of depth 16\t check: -512\r\n128\t trees of depth 18\t check: -128\r\n32\t trees of depth 20\t check: -32\r\nlong lived tree of depth 20\t check: -1\r\n./A +RTS -N4 -H340M -RTS 20 17.08s user 0.30s system 315% cpu 5.511 total\r\n}}}\r\n\r\nHowever, without that GC hint performance deteriorates dramatically,\r\n\r\n{{{\r\n$ time ./A +RTS -N4 -RTS 20 \r\nstretch tree of depth 21\t check: -1\r\n2097152\t trees of depth 4\t check: -2097152\r\n524288\t trees of depth 6\t check: -524288\r\n131072\t trees of depth 8\t check: -131072\r\n32768\t trees of depth 10\t check: -32768\r\n8192\t trees of depth 12\t check: -8192\r\n2048\t trees of depth 14\t check: -2048\r\n512\t trees of depth 16\t check: -512\r\n128\t trees of depth 18\t check: -128\r\n32\t trees of depth 20\t check: -32\r\nlong lived tree of depth 20\t check: -1\r\n./A +RTS -N4 -RTS 20 33.83s user 0.42s system 136% cpu 25.033 total\r\n}}}\r\n\r\nSo 5x slow down. \r\n\r\nCould the GC heap growth algorithm be tuned? Other language runtimes, that are slower than Haskell's on this benchmark when our GC hint is in play, don't seem to suffer as badly without the hint:\r\n\r\n http://shootout.alioth.debian.org/u64q/benchmark.php?test=binarytrees&lang=all\r\n\r\nSee e.g. Erlang. So: is there a better growth algorithm?\r\n\r\n\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/1820Windows segfault-catching only works for the main thread2019-07-07T19:11:35ZSimon MarlowWindows segfault-catching only works for the main threadOn Windows, the RTS tries to catch segmentation faults and divide-by-zero exceptions using structured exception handling in `rts/Main.c`. Unfortunately this only works for the main thread, so if the exception occurs in another thread it ...On Windows, the RTS tries to catch segmentation faults and divide-by-zero exceptions using structured exception handling in `rts/Main.c`. Unfortunately this only works for the main thread, so if the exception occurs in another thread it won't be caught. GHCi runs all its computations in a separate thread, hence `derefnull(ghci)` and `divbyzero(ghci)` are failing.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 6.8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Windows segfault-catching only works for the main thread","status":"New","operating_system":"","component":"Runtime System","related":[],"milestone":"6.8 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.8.1","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Bug","description":"On Windows, the RTS tries to catch segmentation faults and divide-by-zero exceptions using structured exception handling in `rts/Main.c`. Unfortunately this only works for the main thread, so if the exception occurs in another thread it won't be caught. GHCi runs all its computations in a separate thread, hence `derefnull(ghci)` and `divbyzero(ghci)` are failing.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1