mirror of https://github.com/crytic/echidna
parent
bf14ea4f32
commit
8cfe2e7279
@ -0,0 +1,38 @@ |
||||
{-# LANGUAGE TemplateHaskell #-} |
||||
|
||||
module Echidna.CatchMVar (catchMVar, putMVar_, takeMVar_, writeChan_, readChan_) where |
||||
|
||||
import Control.Exception |
||||
import Language.Haskell.TH |
||||
|
||||
-- https://tech.fpcomplete.com/blog/2018/05/pinpointing-deadlocks-in-haskell/ |
||||
catchMVar :: String -> IO a -> IO a |
||||
catchMVar msg action = |
||||
action `catches` |
||||
[ Handler (\exc@BlockedIndefinitelyOnMVar -> putStrLn ("[MVar]: Error at " ++ msg) >> throwIO exc) |
||||
, Handler (\exc@BlockedIndefinitelyOnSTM -> putStrLn ("[STM]: Error at " ++ msg) >> throwIO exc) |
||||
] |
||||
|
||||
printLocation :: Q Exp |
||||
printLocation = do |
||||
loc <- location |
||||
let |
||||
fname = loc_filename loc |
||||
line = fst $ loc_start loc |
||||
msg = fname ++ ":" ++ show line |
||||
litE $ stringL msg |
||||
|
||||
catchMVarTempl :: Q Exp |
||||
catchMVarTempl = [| catchMVar $printLocation |] |
||||
|
||||
putMVar_ :: Q Exp |
||||
putMVar_ = [| ($catchMVarTempl .) . putMVar |] |
||||
|
||||
takeMVar_ :: Q Exp |
||||
takeMVar_ = [| $catchMVarTempl . takeMVar |] |
||||
|
||||
writeChan_ :: Q Exp |
||||
writeChan_ = [| ($catchMVarTempl .) . writeChan |] |
||||
|
||||
readChan_ :: Q Exp |
||||
readChan_ = [| $catchMVarTempl . readChan |] |
Loading…
Reference in new issue