[GHC] #3291: "Thread blocked indefinitely" kills the program despite being caught

GHC trac at galois.com
Thu Jun 11 10:39:49 EDT 2009


#3291: "Thread blocked indefinitely" kills the program despite being caught
---------------------------------+------------------------------------------
    Reporter:  batterseapower    |        Owner:                  
        Type:  bug               |       Status:  closed          
    Priority:  normal            |    Milestone:                  
   Component:  Runtime System    |      Version:  6.10.3          
    Severity:  normal            |   Resolution:  invalid         
    Keywords:                    |   Difficulty:  Unknown         
    Testcase:                    |           Os:  Unknown/Multiple
Architecture:  Unknown/Multiple  |  
---------------------------------+------------------------------------------
Changes (by simonmar):

  * status:  new => closed
  * difficulty:  => Unknown
  * resolution:  => invalid

Old description:

> Perhaps this is just me misunderstanding the semantics of exceptions, but
> the following program:
>
> """
> import Test.HUnit.Lang
> import Control.Concurrent.STM
>
> import Control.Exception
>
> import Control.Concurrent
> import Control.Concurrent.MVar
>
> main = do
>   mv <- newEmptyMVar
>   forkIO $ do
>         r <- performTestCase (atomically retry)
>         print "Yeaahh!"
>         print r
>         evaluate r
>         putMVar mv r
>   print "Cool, let's see what we get"
>   r <- takeMVar mv
>   print r
>   print "Am I printed?"
> """
>
> Should in my opinion, when run, print "Am I printed". This is because the
> "Thread blocked indefinitely" exception is caught by HUnit. However, this
> happens instead:
>
> """
> mbolingbroke at mb566 ~/Junk
> $ ./Repro
> "Cool, let's see what we get"
> "Yeaahh!"
> Just (False,"thread blocked indefinitely")
> Repro: thread blocked indefinitely
> """
>
> NB: I get the expected behaviour if I run it within GHCi, but not if I
> compile the program.
>
> This is causing problems for test-framework (see
> http://bsp.lighthouseapp.com/projects/15661-hs-test-framework/tickets/1
> -exits-immediately-on-thread-blocked-indefinitely-exception#ticket-1-2)

New description:

 Perhaps this is just me misunderstanding the semantics of exceptions, but
 the following program:

 {{{
 import Test.HUnit.Lang
 import Control.Concurrent.STM

 import Control.Exception

 import Control.Concurrent
 import Control.Concurrent.MVar

 main = do
   mv <- newEmptyMVar
   forkIO $ do
         r <- performTestCase (atomically retry)
         print "Yeaahh!"
         print r
         evaluate r
         putMVar mv r
   print "Cool, let's see what we get"
   r <- takeMVar mv
   print r
   print "Am I printed?"
 }}}

 Should in my opinion, when run, print "Am I printed". This is because the
 "Thread blocked indefinitely" exception is caught by HUnit. However, this
 happens instead:

 {{{
 mbolingbroke at mb566 ~/Junk
 $ ./Repro
 "Cool, let's see what we get"
 "Yeaahh!"
 Just (False,"thread blocked indefinitely")
 Repro: thread blocked indefinitely
 }}}

 NB: I get the expected behaviour if I run it within GHCi, but not if I
 compile the program.

 This is causing problems for test-framework (see
 http://bsp.lighthouseapp.com/projects/15661-hs-test-framework/tickets/1
 -exits-immediately-on-thread-blocked-indefinitely-exception#ticket-1-2)

Comment:

 The GC determines which threads are blocked indefinitely: those that are
 unreachable from any root can never be woken up.  So what's happening here
 is that when the forkIO'd thread becomes unreachable, the main thread is
 also unreachable.  Both threads therefore get BlockedIndefinitely
 exceptions.

 If you want the main thread to stay alive, you can add a

 {{{
 myThreadId >>= newStablePtr
 }}}

 to `main`.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3291#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the Glasgow-haskell-bugs mailing list