[GHC] #14521: Infinite loop at runtime when a given function is not marked INLINE

#14521: Infinite loop at runtime when a given function is not marked INLINE -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.2 Keywords: | Operating System: MacOS X Architecture: | Type of failure: Incorrect result Unknown/Multiple | at runtime Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Hello, in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue: When compiling on OSX with optimizations (`stack clean && stack build` with resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered, if the function `Animation.animate'` is not inlined. The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game) The fix is the commit that follows : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276... stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` Could this be a compiler bug? The code is available at https://github.com/OlivierSohn/hamazed I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it. Thank you, Olivier -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by OlivierSohn: Old description:
Hello,
in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue:
When compiling on OSX with optimizations (`stack clean && stack build` with resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered, if the function `Animation.animate'` is not inlined.
The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game)
The fix is the commit that follows : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276...
stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0`
Could this be a compiler bug?
The code is available at https://github.com/OlivierSohn/hamazed
I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it.
Thank you, Olivier
New description: Hello, in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue: When compiling on OSX with optimizations (`stack clean && stack build` with resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered, if the function `Animation.animate'` is not inlined. The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game) I originally fixed this behaviour by declaring the function that consumes the Animator record INLINE : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276... And later, I found that another way to fix the behaviour is to remove the strict annotation on the fields of the record "Animator", ie changing ` data Animator a = Animator { _animatorPure :: !(Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: !(Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: !(Frame -> Color8Code) } ` to: ` data Animator a = Animator { _animatorPure :: (Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: (Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: (Frame -> Color8Code) } Also, here is my stack version if it matters: ` stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` Could this be a compiler bug? The code is available at https://github.com/OlivierSohn/hamazed I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it. Thank you, Olivier -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by OlivierSohn: Old description:
Hello,
in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue:
When compiling on OSX with optimizations (`stack clean && stack build` with resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered, if the function `Animation.animate'` is not inlined.
The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game)
I originally fixed this behaviour by declaring the function that consumes the Animator record INLINE : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276...
And later, I found that another way to fix the behaviour is to remove the strict annotation on the fields of the record "Animator", ie changing
` data Animator a = Animator { _animatorPure :: !(Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: !(Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: !(Frame -> Color8Code) } `
to:
` data Animator a = Animator { _animatorPure :: (Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: (Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: (Frame -> Color8Code) }
Also, here is my stack version if it matters: ` stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0`
Could this be a compiler bug?
The code is available at https://github.com/OlivierSohn/hamazed
I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it.
Thank you, Olivier
New description: Hello, in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue: When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug. The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game) I originally fixed this behaviour by pragma-declaring INLINE the function `Animation.animate' (this function consumes an Animator record) : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276... And later, I found that another way to fix the behaviour is to remove the strict annotation on the fields of the record "Animator", ie changing ` data Animator a = Animator { _animatorPure :: !(Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: !(Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: !(Frame -> Color8Code) } ` to: ` data Animator a = Animator { _animatorPure :: (Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: (Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: (Frame -> Color8Code) } Could this be a compiler bug? The code is available at https://github.com/OlivierSohn/hamazed I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it. Also, here is my stack version if it matters: ` stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` Thank you, Olivier -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): Yes, it could be a compiler bug, but a more self-contained repro case would be far far easier to deal with. Thank you! Does it happen with 8.2? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): Replying to [comment:3 simonpj]:
Yes, it could be a compiler bug, but a more self-contained repro case would be far far easier to deal with. Thank you!
Does it happen with 8.2?
Ok, I'll try to reduce the problem to a minimal amount of code. I was waiting to be sure that it was not a problem in my code before digging a little deeper. I don't know if it's a bug fixed by 8.2, I'll try that too. First I need to understand how to build using ghc directly instead of relying on stack, because latest stack version references 8.0.2 :) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * milestone: => 8.2.3 Old description:
Hello,
in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue:
When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug.
The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game)
I originally fixed this behaviour by pragma-declaring INLINE the function `Animation.animate' (this function consumes an Animator record) : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276...
And later, I found that another way to fix the behaviour is to remove the strict annotation on the fields of the record "Animator", ie changing
` data Animator a = Animator { _animatorPure :: !(Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: !(Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: !(Frame -> Color8Code) } `
to:
` data Animator a = Animator { _animatorPure :: (Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: (Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: (Frame -> Color8Code) }
Could this be a compiler bug?
The code is available at https://github.com/OlivierSohn/hamazed
I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it.
Also, here is my stack version if it matters: ` stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0`
Thank you, Olivier
New description: Hello, in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue: When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug. The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game) I originally fixed this behaviour by pragma-declaring INLINE the function `Animation.animate' (this function consumes an Animator record) : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276... And later, I found that another way to fix the behaviour is to remove the strict annotation on the fields of the record "Animator", ie changing {{{ data Animator a = Animator { _animatorPure :: !(Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: !(Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: !(Frame -> Color8Code) } }}} to: {{{ data Animator a = Animator { _animatorPure :: (Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: (Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: (Frame -> Color8Code) } }}} Could this be a compiler bug? The code is available at https://github.com/OlivierSohn/hamazed I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it. Also, here is my stack version if it matters: {{{ stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` }}} Thank you, Olivier -- Comment: For what it's worth the repo build for me with 8.2.1, {{{ $ git clone https://github.com/OlivierSohn/hamazed $ cd hamazed $ git checkout 9f25223ef0502f91cd9633654bdb172f714c3920 $ git clone https://github.com/OlivierSohn/ansi-terminal.git $ git -C ansi-terminal checkout e6a2b1ff2e1aebd902c1791583b80ef481f370c5 $ echo "packages: ., ansi-terminal" >> cabal.project $ cabal new-build all --allow-newer }}} Unfortunately I'm quite lost regarding the game itself. I found that pressing "Enter" makes numbers start flying about; however the `s`, `e`, `d`, `f` keys don't appear to do anything. This appears to be the case with both 8.2.2 and 8.0.2. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

For what it's worth the repo build for me with 8.2.1, {{{ $ git clone https://github.com/OlivierSohn/hamazed $ cd hamazed $ git checkout 9f25223ef0502f91cd9633654bdb172f714c3920 $ git clone https://github.com/OlivierSohn/ansi-terminal.git $ git -C ansi-terminal checkout e6a2b1ff2e1aebd902c1791583b80ef481f370c5 $ echo "packages: ., ansi-terminal" >> cabal.project $ cabal new-build all --allow-newer }}} Unfortunately I'm quite lost regarding the game itself. I found that
#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): Replying to [comment:5 bgamari]: pressing "Enter" makes numbers start flying about; however the `s`, `e`, `d`, `f` keys don't appear to do anything. This appears to be the case with both 8.2.2 and 8.0.2. @bgamari, I suppose you are on windows? On windows there is a bug which makes it impossible to set stdin buffering mode to "unbuffered" (I explain a bit more in BACKLOG.md file, in "Windows" chapter), this explains the behaviour you see: when pressing Enter, stdin is flushed. I tried to circumvent this problem but didn't finish the fix. In the meantime I made a program that allows to reproduce the behaviour with minimal code : it is branch https://github.com/OlivierSohn/hamazed/tree/repro-ghc-14521-A When running the program, the expected output is: ` Before rendering animations animation is rendered After rendering animations ` What I see with 8.0.2 when compiled with optimizations is: ` Before rendering animations ` I also documented in the code what changes make the problem disappear I'd be interested if someone can build with optimizations with 8.2.2 and run the program and report on the output ? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by OlivierSohn: Old description:
Hello,
in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue:
When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug.
The bug is visible at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game)
I originally fixed this behaviour by pragma-declaring INLINE the function `Animation.animate' (this function consumes an Animator record) : https://github.com/OlivierSohn/hamazed/commit/597619bb14974d2bbacfb284a9e276...
And later, I found that another way to fix the behaviour is to remove the strict annotation on the fields of the record "Animator", ie changing
{{{ data Animator a = Animator { _animatorPure :: !(Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: !(Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: !(Frame -> Color8Code) } }}}
to:
{{{ data Animator a = Animator { _animatorPure :: (Iteration -> (Coords -> Location) -> Tree -> Tree) , _animatorIO :: (Tree -> StepType -> Animation -> (Coords -> Location) -> RenderState -> IO (Maybe Animation)) , _animatorColorFromFrame :: (Frame -> Color8Code) } }}}
Could this be a compiler bug?
The code is available at https://github.com/OlivierSohn/hamazed
I could try to create another program that reproduces the issue more easily (without having to play the game), just let me know if you need it.
Also, here is my stack version if it matters: {{{ stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` }}}
Thank you, Olivier
New description: Hello, in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue: When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug. The bug is visible in the full game at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game) And this commit shows a program with minimal code to reproduce the issue : https://github.com/OlivierSohn/hamazed/commit/30b0f703565a4150d686a36a4dfe9d... The expected output of the program is {{{ Before rendering animations animation is rendered After rendering animations }}} What I observe is {{{ Before rendering animations }}} I found several ways to circumvent the problem, wrote them in the code to help debugging. Also, here is my stack version if it matters: {{{ stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` }}} Thank you, Olivier -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by svenpanne): Replying to [comment:4 OlivierSohn]:
[...] First I need to understand how to build using ghc directly instead of relying on stack, because latest stack version references 8.0.2 :)
Just FYI: Stackage nightly builds use 8.2.1/8.2.2 for some time now, just use `stack --resolver=nightly ...` or even more specifically e.g. `stack --resolver=nightly-2017-11-25 ...`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.0.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): Replying to [comment:8 svenpanne]:
Just FYI: Stackage nightly builds use 8.2.1/8.2.2 for some time now, just use `stack --resolver=nightly ...` or even more specifically e.g. `stack --resolver=nightly-2017-11-25 ...`.
Thanks, using the nightly resolver I could verify that the behaviour is the same on 8.2.2: {{{ 2017-11-25 21:01:48.402994: [debug] Run process: /Users/Olivier/Dev/hs.maze/.stack- work/install/x86_64-osx/nightly-2017-11-25/8.2.2/bin/hamazed-exe @(Stack/Exec.hs:67:5) Before rendering animations }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by OlivierSohn): * version: 8.0.2 => 8.2.2 Old description:
Hello,
in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue:
When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug.
The bug is visible in the full game at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game)
And this commit shows a program with minimal code to reproduce the issue : https://github.com/OlivierSohn/hamazed/commit/30b0f703565a4150d686a36a4dfe9d...
The expected output of the program is
{{{ Before rendering animations animation is rendered After rendering animations }}}
What I observe is
{{{ Before rendering animations }}}
I found several ways to circumvent the problem, wrote them in the code to help debugging.
Also, here is my stack version if it matters: {{{ stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` }}}
Thank you, Olivier
New description: Hello, in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue: **(Edit : the same behaviour exists with ghc 8.2.2)** When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug. The bug is visible in the full game at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game) And this commit shows a program with minimal code to reproduce the issue : https://github.com/OlivierSohn/hamazed/commit/30b0f703565a4150d686a36a4dfe9d... The expected output of the program is {{{ Before rendering animations animation is rendered After rendering animations }}} What I observe is {{{ Before rendering animations }}} I found several ways to circumvent the problem, wrote them in the code to help debugging. Also, here is my stack version if it matters: {{{ stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` }}} Thank you, Olivier -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): Replying to [comment:3 simonpj]:
Yes, it could be a compiler bug, but a more self-contained repro case would be far far easier to deal with. Thank you!
Does it happen with 8.2?
I verified that it happens also with 8.2.2, and made a minimal repro case in this branch : https://github.com/OlivierSohn/hamazed/tree/repro- ghc-14521-A It can be built and run with this command: {{{ stack build --pedantic --resolver=nightly --install-ghc&& stack exec hamazed-exe --resolver=nightly -v }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by OlivierSohn): * priority: normal => high -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): I raised the priority as this bug it prevents me from refactoring code because I need constantly to make sure that the bug is not happening again. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): That looks like a good minimal example but you still have lots of unnecessary dependencies in the cabal file. Unless the project can be compiled with a single invocation of ghc or cabal then it is unlikely someone will make quick progress. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime when either : a given function is not marked INLINE, or functions are stored in strict field -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): @mpickering Thanks for the feedback, so now I removed all dependencies from the cabal file. I also found out that if the Animation module is entirely exported : {{{ module Animation where }}} It fixes the problem! I added this observation in the comments. Here is the branch : https://github.com/OlivierSohn/hamazed/tree/repro- ghc-14521-A -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): I rename the title because there are actually more ways to circumvent the problem, which are all documented in the code. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:16 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Old description:
Hello,
in https://github.com/OlivierSohn/hamazed/issues/1 I describe the following issue:
**(Edit : the same behaviour exists with ghc 8.2.2)**
When compiling on OSX with optimizations (`stack clean && stack build` using resolver `lts-9.12` (ghc 8.0.2)), the program loops infinitely (400% CPU, and execution is blocked) when an animation is triggered in the game. When compiling without optimizations, there is not this bug.
The bug is visible in the full game at this commit : https://github.com/OlivierSohn/hamazed/commit/9f25223ef0502f91cd9633654bdb17... (to reproduce, shoot at a number in the game)
And this commit shows a program with minimal code to reproduce the issue : https://github.com/OlivierSohn/hamazed/commit/30b0f703565a4150d686a36a4dfe9d...
The expected output of the program is
{{{ Before rendering animations animation is rendered After rendering animations }}}
What I observe is
{{{ Before rendering animations }}}
I found several ways to circumvent the problem, wrote them in the code to help debugging.
Also, here is my stack version if it matters: {{{ stack version: `1.3.2, Git revision 3f675146590da4f3edf768b89355f798229da2a5 (4395 commits) x86_64 hpack-0.15.0` }}}
Thank you, Olivier
New description: Hello, For this program : https://github.com/OlivierSohn/hamazed/tree/repro- ghc-14521-A The expected output is: {{{ Before rendering animations animation is rendered After rendering animations }}} What I observe is when compiling with ghc 8.0.2 or 8.2.2, with optimizations: {{{ Before rendering animations }}} I found several ways to circumvent the bug, and documented each one in the source code. Can someone take a look? Is my program an invalid program that was not detected by the compiler? Thank you, Olivier -- Comment (by OlivierSohn): I update the description to reference the branch of the repro case and not a particular commit, and to be more concise. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by OlivierSohn): * os: MacOS X => Unknown/Multiple Comment: I verified I can reproduce it on OS X and Windows -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:18 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: new Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): For the record, I am seeing the program loop in `Animation_zdwanimatedNumber_info`. Indeed looking at the simplified Core, the "bad" configuration compiles to {{{#!hs -- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} Animation.$wanimatedNumber [InlPrag=[0], Occ=LoopBreaker] :: GHC.Prim.Int# -> Tree -> Animation -> IO (Maybe Animation) [GblId, Arity=1, Caf=NoCafRefs, Str=b] Animation.$wanimatedNumber = \ (ww_s3v3 :: GHC.Prim.Int#) -> Animation.$wanimatedNumber ww_s3v3 end Rec } }}} Bad news bears. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:19 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => closed * resolution: => invalid Comment: So I'm not certain why the program runs successfully without optimization, but it seems to me like the compiler indeed loop. The gist of the program (eliminating some irrelevant bits) is {{{#!hs data Animator a = Animator { _animatorIO :: !(Tree -> Animation -> IO (Maybe Animation)) } mkAnimator :: (t -> Tree -> Animation -> IO (Maybe Animation)) -> t -> Animator a mkAnimator io_ params = Animator (io_ params) animatedNumber :: Int -> Tree -> Animation -> IO (Maybe Animation) animatedNumber n = animate' (mkAnimator animatedNumber n) }}} After inlining `mkAnimator` into `animatedNumber` and expressing the constructor's strictness explicitly we have, {{{#!hs animatedNumber :: Int -> Tree -> Animation -> IO (Maybe Animation) animatedNumber n = animate' (let x = animatedNumber n in x `seq` Animator x) }}} Consequently if `animate'` demands its argument the program will loop. This function is defined as, {{{#!hs animate' :: Animator a -> Tree -> Animation -> IO (Maybe Animation) animate' (Animator pure_ io_) = animate pure_ io_ }}} Which indeed does demand its argument. Moreover, this is consistent with your observation that adding an `INLINE` on `animate'` eliminates the loop (since in the real program `Animator` contains two fields, only the first, which I elided above, is needed). Given this, it seems like looping is a completely valid compilation of this program. I would remove the bang from the constructor if laziness is needed (which it seems it is). -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:20 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): I took a quick look. To me it looks as if it should definitely loop. Look at the code {{{ animatedNumber n = animate' (mkAnimator animateNumberPure animatedNumber n) mkAnimator pure_ io_ params = Animator (applyAnimation (pure_ params)) (io_ params) animate' (Animator pure_ io_) = animate pure_ io_ }}} If we just inline `mkAnimator` we see: {{{ animatedNumber n = animate' (Animator blah (animatedNumber n)) }}} Now * `Aminator` is declared to be strict in its second argument * `animate'` is certainly strict So of course `animatedNumber n` will just return bottom. The mystery is not why it diverges -- it should! -- but rather why it sometimes fails to diverge. The answer is that GHC allows itself a bit of leeway in making a divergent program into one that converges, in the interests of improving runtimes generally by allowing more optimisations. You can switch off this behaviour by using `-fpedantic-bottoms`, and then sure enough it always diverges. In this case the relevant optimisation is eta-expansion. If you do manual eta-expansion on `animate'`, then it converges, always: {{{ animate' :: Animator a -> Tree -> Animation -> IO (Maybe Animation) animate' (Animator pure_ io_) t a = animate pure_ io_ t a }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:21 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): Replying to [comment:21 simonpj]:
In this case the relevant optimisation is eta-expansion. If you do manual eta-expansion on `animate'`, then it converges, always: {{{ animate' :: Animator a -> Tree -> Animation -> IO (Maybe Animation) animate' (Animator pure_ io_) t a = animate pure_ io_ t a }}}
Thank you for your analysis, I think I understand why making the record field non-strict fixes the problem, but I don't understand why the eta- expansion also fixes it, could you explain me or point me to a resource explaining this point? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:22 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by OlivierSohn): Replying to [comment:20 bgamari]: Thanks for your explanations! I'm not used to think in term of strict / lazy evaluation so I'll need to re-read them a few times until I understand everything :) As a default I was told to use strict fields to avoid accumulating thunks, and it's the first time I encounter a problem where I actually need lazyness. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:23 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC