diff --git a/Test/Framework/Runners/Console/Utilities.hs b/Test/Framework/Runners/Console/Utilities.hs
--- a/Test/Framework/Runners/Console/Utilities.hs
+++ b/Test/Framework/Runners/Console/Utilities.hs
@@ -4,9 +4,7 @@
 
 import System.Console.ANSI
 
-import Control.Exception
-
-import Prelude hiding (catch)
+import Control.Exception.Extensible
 
 
 hideCursorDuring :: IO a -> IO a
diff --git a/Test/Framework/Runners/ThreadPool.hs b/Test/Framework/Runners/ThreadPool.hs
--- a/Test/Framework/Runners/ThreadPool.hs
+++ b/Test/Framework/Runners/ThreadPool.hs
@@ -8,7 +8,9 @@
 
 import qualified Data.IntMap as IM
 
+import Foreign.StablePtr
 
+
 data WorkerEvent token a = WorkerTermination
                          | WorkerItem token a
 
@@ -32,6 +34,26 @@
     
     -- Spawn workers
     forM_ [1..n] (const $ forkIO $ poolWorker input_chan output_chan)
+
+    -- Short version: make sure we do the right thing if a test blocks on dead
+    -- MVars or TVars.
+    -- Long version: GHC is clever enough to throw an exception (BlockedOnDeadMVar
+    -- or BlockedIndefinitely) when a thread is waiting for a MVar or TVar that can't
+    -- be written to. However, it doesn't know anything about the handlers for those
+    -- exceptions. Therefore, when a worker runs a test that causes this exception,
+    -- since the main thread is blocking on the worker, the main thread gets the
+    -- exception too despite the fact that the main thread will be runnable as soon
+    -- as the worker catches its own exception. The below makes sure the main thread
+    -- is always reachable by the GC, which is the mechanism for finding threads
+    -- that are unrunnable.
+    -- See also the ticket where SimonM (semi-cryptically) explains this:
+    -- http://hackage.haskell.org/trac/ghc/ticket/3291
+    --
+    -- NB: this actually leaks stable pointers. We could prevent this by making
+    -- takeWhileWorkersExist do |unsafePerformIO newStablePtr| when returning the
+    -- lazily-demanded tail of the list, but its a bit of a pain. For now, just
+    -- grit our teeth and accept the leak.
+    _stablePtr <- myThreadId >>= newStablePtr
     
     -- Return the results generated by the worker threads lazily and in
     -- the same order as we got the inputs
diff --git a/test-framework.cabal b/test-framework.cabal
--- a/test-framework.cabal
+++ b/test-framework.cabal
@@ -1,5 +1,5 @@
 Name:                test-framework
-Version:             0.2.3
+Version:             0.2.4
 Cabal-Version:       >= 1.2.3
 Category:            Testing
 Synopsis:            Framework for running and organising tests, with HUnit and QuickCheck support
@@ -44,7 +44,8 @@
                                 Test.Framework.Runners.TimedConsumption
                                 Test.Framework.Utilities
         
-        Build-Depends:          ansi-terminal >= 0.4.0, ansi-wl-pprint >= 0.4.0, regex-posix >= 0.72
+        Build-Depends:          ansi-terminal >= 0.4.0, ansi-wl-pprint >= 0.4.0,
+                                regex-posix >= 0.72, extensible-exceptions >= 0.1.1
         if flag(splitBase)
                 Build-Depends:          base >= 3 && < 5, random >= 1.0, containers >= 0.1
         else
