Opened 3 years ago

Closed 3 years ago

#10231 closed bug (worksforme)

TMVar - fmap - orElse clashes in ghc 7.8.4

Reported by: ran Owned by:
Priority: normal Milestone:
Component: libraries (other) Version: 7.8.4
Keywords: Cc:
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: Incorrect result at runtime Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Attached is a tar archive with minimal reproducible example.

The problem is that after orElse success I get wrong constructor: I should have timer tick but get reset instead. That is, expected output is

timer thread
timer tick
timer thread
timer tick
...

but I get

timer thread
reset
timer thread
reset
...

The strange thing is that the problem presents, first, only when the binary is built by cabal (checked only inside sandbox):

$ cabal sandbox init
...
$ cabal configure
Resolving dependencies...
Configuring mvk-0.1.0.0...
cabal: At least the following dependencies are missing:
stm ==2.4.4
$ cabal install --dependencies-only
...
$ cabal build

When I run

cabal exec -- ghc --make mvk.hs

the resulting binary doesn't show the problem.

Also, problem disappears if I:

  • either comment start of the (long-sleeping) reset thread at all;
  • or change content type of one of TMVars to, say, Bool

But if I change type of content for both to, say, Bool, the problem presents. Furthermore, if with Bool content type I put False in timer thread and True in reset thread (and derive Show and output received value) I get

timer thread
received Reset False
reset
...

That is, underlying Bool is right, but fmapped constructor is wrong.

The problem was absent in Debian Wheezy's ghc 7.4.1 (not sure about STM version).

Reproduced both in

  • Debian Jessie on x86_64 with GHC 7.8.4 binary from official site and cabal-install 1.20.0.3 from deb.haskell.org
  • Debian Wheezy on x86 with GHC 7.8.3 binary from deb.haskell.org and cabal-install 1.20.0.3 built by GHC from dist.

In all cases used cabal.config from Stackage's lts-1.4 (included in the attached archive)

Output from cabal build -v:

Skipping add-source deps check...
Using a sandbox located at
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox
The sandbox was created after the package was already configured.
Re-configuring with most recently used options. If this fails, please run
configure manually.
Using a sandbox located at
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox
'/opt/ghc/7.8.4/bin/ghc' '--numeric-version'
looking for tool ghc-pkg near compiler in /opt/ghc/7.8.4/bin
found ghc-pkg in /opt/ghc/7.8.4/bin/ghc-pkg
'/opt/ghc/7.8.4/bin/ghc-pkg' '--version'
'/opt/ghc/7.8.4/bin/ghc' '--supported-languages'
'/opt/ghc/7.8.4/bin/ghc' '--info'
Reading available packages...
Reading available packages...
Choosing modular solver.
Resolving dependencies...
Configuring mvk-0.1.0.0...
Dependency base ==4.7.0.2: using base-4.7.0.2
Dependency stm ==2.4.4: using stm-2.4.4
Using Cabal-1.20.0.0 compiled by ghc-7.4
Using compiler: ghc-7.8.4
Using install prefix:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox
Binaries installed in:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/bin
Libraries installed in:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/lib/x86_64-linux-ghc-7.8.4/mvk-0.1.0.0
Private binaries installed in:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/libexec
Data files installed in:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/share/x86_64-linux-ghc-7.8.4/mvk-0.1.0.0
Documentation installed in:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/share/doc/x86_64-linux-ghc-7.8.4/mvk-0.1.0.0
Configuration files installed in:
/.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/etc
Using alex version 3.1.3 found on system at: /usr/bin/alex
Using ar found on system at: /usr/bin/ar
No c2hs found
No cpphs found
No ffihugs found
Using gcc version 4.9.2 found on system at: /usr/bin/gcc
Using ghc version 7.8.4 found on system at: /opt/ghc/7.8.4/bin/ghc
Using ghc-pkg version 7.8.4 found on system at: /opt/ghc/7.8.4/bin/ghc-pkg
No greencard found
Using haddock version 2.14.3 found on system at: /opt/ghc/7.8.4/bin/haddock
Using happy version 1.19.4 found on system at: /usr/bin/happy
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.67 found on system at: /opt/ghc/7.8.4/bin/hpc
Using hsc2hs version 0.67 found on system at: /opt/ghc/7.8.4/bin/hsc2hs
Using hscolour version 1.20 found on system at: /usr/bin/HsColour
No hugs found
No jhc found
Using ld found on system at: /usr/bin/ld
No lhc found
No lhc-pkg found
No nhc98 found
Using pkg-config version 0.28 found on system at: /usr/bin/pkg-config
Using strip found on system at: /usr/bin/strip
Using tar found on system at: /bin/tar
No uhc found
Component build order: executable 'mvk'
creating dist/build
creating dist/build/autogen
Building mvk-0.1.0.0...
Preprocessing executable 'mvk' for mvk-0.1.0.0...
Building executable mvk...
creating dist/build/mvk
creating dist/build/mvk/mvk-tmp
/opt/ghc/7.8.4/bin/ghc --make -no-link -fbuilding-cabal-package -O -j4 -static -outputdir dist/build/mvk/mvk-tmp -odir dist/build/mvk/mvk-tmp -hidir dist/build/mvk/mvk-tmp -stubdir dist/build/mvk/mvk-tmp -i -idist/build/mvk/mvk-tmp -i. -idist/build/autogen -Idist/build/autogen -Idist/build/mvk/mvk-tmp -optP-include -optPdist/build/autogen/cabal_macros.h -hide-all-packages -no-user-package-db -package-db /.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/x86_64-linux-ghc-7.8.4-packages.conf.d -package-db dist/package.conf.inplace -package-id base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1 -package-id stm-2.4.4-c36cb8072081a12d13d98a3b4449e55c -XHaskell98 ./mvk.hs -Wall
Linking...
/opt/ghc/7.8.4/bin/ghc --make -fbuilding-cabal-package -O -static -outputdir dist/build/mvk/mvk-tmp -odir dist/build/mvk/mvk-tmp -hidir dist/build/mvk/mvk-tmp -stubdir dist/build/mvk/mvk-tmp -i -idist/build/mvk/mvk-tmp -i. -idist/build/autogen -Idist/build/autogen -Idist/build/mvk/mvk-tmp -optP-include -optPdist/build/autogen/cabal_macros.h -hide-all-packages -no-user-package-db -package-db /.main/home/ran/src/transas/knei24/mvk.bug/.cabal-sandbox/x86_64-linux-ghc-7.8.4-packages.conf.d -package-db dist/package.conf.inplace -package-id base-4.7.0.2-bfd89587617e381ae01b8dd7b6c7f1c1 -package-id stm-2.4.4-c36cb8072081a12d13d98a3b4449e55c -XHaskell98 ./mvk.hs -o dist/build/mvk/mvk -Wall
Linking dist/build/mvk/mvk ...

Attachments (1)

mvk-bug.tar.gz (8.1 KB) - added by ran 3 years ago.
reproducing example

Download all attachments as: .zip

Change History (3)

Changed 3 years ago by ran

Attachment: mvk-bug.tar.gz added

reproducing example

comment:1 Changed 3 years ago by fryguybob

When using unsafePerformIO to make a global mutable variable like timerTM in your program you also need to have a NOINLINE pragma {-# NOINLINE timerTM #-} to avoid separate variables due to inlining (see top level mutable state):

timerTM :: TMVar ()
{-# NOINLINE timerTM #-}
timerTM = unsafePerformIO $ newEmptyTMVarIO

resetTM :: TMVar ()
{-# NOINLINE resetTM #-}
resetTM = unsafePerformIO $ newEmptyTMVarIO

Can you try your test again with this change?

comment:2 in reply to:  1 Changed 3 years ago by ran

Resolution: worksforme
Status: newclosed

NOINLINE helps, thank you

Note: See TracTickets for help on using tickets.