Weird behavior of the NonTermination exception
Hello, Before I turn the following into a ticket I want to ask if I miss something obvious: When I run the following program: - import Prelude hiding (catch) import Control.Exception import Control.Concurrent main :: IO () main = do mv - newEmptyMVar _ - forkIO $ do catch action (\e - putStrLn $ I solved the Halting Problem: ++ show (e :: SomeException)) putStrLn putting MVar... putMVar mv () putStrLn putted MVar takeMVar mv action :: IO () action = let x = x in x - I get the output: $ ghc --make Loop.hs -o loop -O2 -fforce-recomp ./loop [1 of 1] Compiling Main ( Loop.hs, Loop.o ) Linking loop ... loop: thread blocked indefinitely in an MVar operation I solved the Halting Problem: loop putting MVar... putted MVar As can be seen, the putMVar is executed successfully. So why do I get the message: thread blocked indefinitely in an MVar operation? Note that if I change the action to a normal error the message disappears. I discovered this bug when hunting for another one. I have a Haskell web-server where one of the request handlers contained a loop. All exceptions thrown by handlers are caught and logged. When executing the looping handler I noticed ~0% CPU usage so I assumed that the handler wasn't actually looping because a NonTermination exception was thrown. However for some reason the NonTermination exception was not caught and logged. I haven't yet isolated this bug into a small test-case but when trying that I discovered the above. Regards, Bas ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Weird behavior of the NonTermination exception
Excerpts from Bas van Dijk's message of Thu May 03 11:10:38 -0400 2012: As can be seen, the putMVar is executed successfully. So why do I get the message: thread blocked indefinitely in an MVar operation? GHC will send BlockedIndefinitelyOnMVar to all threads involved in the deadlock, so it's not unusual that this can interact with error handlers to cause the system to become undeadlocked. http://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/ However, I must admit I am a bit confused as for the timing of the thrown exceptions. Edward ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Weird behavior of the NonTermination exception
On 3 May 2012 17:31, Edward Z. Yang ezy...@mit.edu wrote: Excerpts from Bas van Dijk's message of Thu May 03 11:10:38 -0400 2012: As can be seen, the putMVar is executed successfully. So why do I get the message: thread blocked indefinitely in an MVar operation? GHC will send BlockedIndefinitelyOnMVar to all threads involved in the deadlock, so it's not unusual that this can interact with error handlers to cause the system to become undeadlocked. But why is the BlockedIndefinitelyOnMVar thrown in the first place? According to the its documentation and your very enlightening article it is thrown when: The thread is blocked on an MVar, but there are no other references to the MVar so it can't ever continue. The first condition holds for the main thread since it's executing takeMVar. But the second condition doesn't hold since the forked thread still has a reference to the MVar. I just tried delaying the thread before the putMVar: - main :: IO () main = do mv - newEmptyMVar _ - forkIO $ do catch action (\e - putStrLn $ I solved the Halting Problem: ++ show (e :: SomeException)) putStrLn Delaying for 2 seconds... threadDelay 200 putStrLn putting MVar... putMVar mv () putStrLn putted MVar takeMVar mv - Now I get the following output: loop: thread blocked indefinitely in an MVar operation I solved the Halting Problem: loop Delaying for 2 seconds... Now it seems the thread is killed while delaying. But why is it killed? It could be a BlockedIndefinitelyOnMVar that is thrown. However I get the same output when I catch and print all exceptions in the forked thread: main :: IO () main = do mv - newEmptyMVar _ - forkIO $ handle (\e - putStrLn $ Oh nooo: ++ show (e :: SomeException)) $ do catch action (\e - putStrLn $ I solved the Halting Problem: ++ show (e :: SomeException)) putStrLn Delaying for 2 seconds... threadDelay 200 putStrLn putting MVar... putMVar mv () putStrLn putted MVar takeMVar mv Bas ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Weird behavior of the NonTermination exception
On 3 May 2012 18:14, Bas van Dijk v.dijk@gmail.com wrote: Now it seems the thread is killed while delaying. But why is it killed? Oh I realise the forked thread is killed because the main thread terminates because it received a BlockedIndefinitelyOnMVar exception and then all daemonic threads are killed. Bas ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users