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