Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,345
    • Issues 5,345
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 567
    • Merge requests 567
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #5866
Closed
Open
Issue created Feb 12, 2012 by joeyadams@trac-joeyadams

Interrupting interleaved STM and resuming it produces segfault

The following program produces a segfault:

import Control.Concurrent.STM
import Control.Exception
import System.IO.Unsafe
import System.Timeout

main :: IO ()
main = do
    x <- unsafeInterleaveIO $ atomically retry
    _ <- timeout 1000000 $ evaluate x
    evaluate x

When a thread is interrupted while evaluating interleaved IO, and that IO is blocked on an STM transaction, resuming the suspended computation produces a segfault.

This segfault happens with GHC 7.0.3, 7.2.2, and 7.4.1, on both Windows 32-bit and Linux 64-bit, with and without -threaded.

Compiling with -debug on 7.5.20120211, I get an assertion failure in rts/STM.c, line 1525:

ASSERT (trec != NO_TREC);

In general, pure computations are not always suspended by asynchronous exceptions:

import Control.Concurrent
import System.IO.Unsafe
import System.Timeout

main :: IO ()
main = do
    -- Resuming interleaved takeMVar works correctly
    mv <- newEmptyMVar
    _ <- forkIO $ threadDelay 2000000 >> putMVar mv "Hello"
    s <- unsafeInterleaveIO $ takeMVar mv
    _ <- timeout 1000000 $ putStrLn s
    putStrLn s

    -- But resuming getLine repeats the asynchronous exception, contrary to the
    -- documentation of 'throwTo'
    s <- unsafeInterleaveIO getLine
    _ <- timeout 1000000 $ putStrLn s
    putStrLn s

Note issue #5859 (closed) when testing: unsafeInterleaveIO being INLINE causes computations to be duplicated when shared among threads. The examples above dodge this issue by keeping the work in the current thread.

Trac metadata
Trac field Value
Version 7.4.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Runtime System
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking