Skip to content

Commit ed15e8e

Browse files
committed
Introduce DebuggeeAction-monad
* Introduce DebuggeeAction as alias for StateT Debugee IO -> Get rid of Debuggee being passed explicitly into IO actions, turning function signatures like (Debuggee -> ... -> IO a) into (... -> DebuggeeAction a) * This is done in order to track state in Debuggee in the future. * Introduce a lot of liftIO :(
1 parent 24d4886 commit ed15e8e

File tree

6 files changed

+207
-167
lines changed

6 files changed

+207
-167
lines changed

client/ghc-debug-client.cabal

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ library
1919
network >=2.6 && <2.7,
2020
unordered-containers,
2121
ghc-debug-common, cpu,
22-
dwarfadt, dwarf-el, text, process, filepath, directory
22+
dwarfadt, dwarf-el, text, process, filepath, directory,
23+
mtl
2324
hs-source-dirs: src
24-
default-language: Haskell2010
25+
default-language: Haskell2010

client/src/GHC/Debug/Client.hs

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module GHC.Debug.Client
22
( Debuggee
3+
, DebuggeeAction
4+
, applyDebuggeeAction
35
, withDebuggee
46
, withDebuggeeSocket
57
, pauseDebuggee
@@ -26,6 +28,7 @@ module GHC.Debug.Client
2628
import Control.Concurrent
2729
import Control.Exception
2830
import Control.Monad
31+
import Control.Monad.State.Lazy
2932
import GHC.Debug.Types
3033
import GHC.Debug.Decode
3134
import GHC.Debug.Decode.Stack
@@ -55,11 +58,17 @@ import System.Directory
5558
import Text.Printf
5659

5760
data Debuggee = Debuggee { debuggeeHdl :: Handle
58-
, debuggeeInfoTblEnv :: MVar (HM.HashMap InfoTablePtr RawInfoTable)
61+
, debuggeeInfoTblEnv :: HM.HashMap InfoTablePtr RawInfoTable
5962
, debuggeeDwarf :: Maybe Dwarf
6063
, debuggeeFilename :: FilePath
6164
}
6265

66+
type DebuggeeAction a = StateT Debuggee IO a
67+
68+
69+
applyDebuggeeAction :: Debuggee -> DebuggeeAction a -> IO a
70+
applyDebuggeeAction = flip evalStateT
71+
6372

6473
debuggeeProcess :: FilePath -> FilePath -> IO CreateProcess
6574
debuggeeProcess exe sockName = do
@@ -69,7 +78,7 @@ debuggeeProcess exe sockName = do
6978

7079
-- | Open a debuggee, this will also read the DWARF information
7180
withDebuggee :: FilePath -- ^ path to executable
72-
-> (Debuggee -> IO a)
81+
-> DebuggeeAction a
7382
-> IO a
7483
withDebuggee exeName action = do
7584
let sockName = "/tmp/ghc-debug2"
@@ -86,33 +95,39 @@ withDebuggee exeName action = do
8695
withDebuggeeSocket :: FilePath -- ^ executable name of the debuggee
8796
-> FilePath -- ^ debuggee's socket location
8897
-> Maybe Dwarf
89-
-> (Debuggee -> IO a)
98+
-> DebuggeeAction a
9099
-> IO a
91100
withDebuggeeSocket exeName sockName mdwarf action = do
92101
s <- socket AF_UNIX Stream defaultProtocol
93102
connect s (SockAddrUnix sockName)
94103
hdl <- socketToHandle s ReadWriteMode
95-
infoTableEnv <- newMVar mempty
96-
action (Debuggee hdl infoTableEnv mdwarf exeName)
104+
evalStateT action (Debuggee hdl mempty mdwarf exeName)
97105

98106
-- | Send a request to a 'Debuggee' paused with 'pauseDebuggee'.
99-
request :: Debuggee -> Request resp -> IO resp
100-
request d req = doRequest (debuggeeHdl d) req
107+
request :: Request resp -> DebuggeeAction resp
108+
request req = do
109+
hdl <- gets debuggeeHdl
110+
liftIO $ doRequest hdl req
101111

102-
lookupInfoTable :: Debuggee -> RawClosure -> IO (RawInfoTable, RawClosure)
103-
lookupInfoTable d rc = do
112+
lookupInfoTable :: RawClosure -> DebuggeeAction (RawInfoTable, RawClosure)
113+
lookupInfoTable rc = do
104114
let ptr = getInfoTblPtr rc
105-
itblEnv <- readMVar (debuggeeInfoTblEnv d)
115+
itblEnv <- gets debuggeeInfoTblEnv
106116
case HM.lookup ptr itblEnv of
107117
Nothing -> do
108-
[itbl] <- request d (RequestInfoTables [ptr])
109-
modifyMVar_ (debuggeeInfoTblEnv d) $ return . HM.insert ptr itbl
118+
[itbl] <- request (RequestInfoTables [ptr])
119+
infoTblEnv <- gets debuggeeInfoTblEnv
120+
modify' $ \s -> s { debuggeeInfoTblEnv = HM.insert ptr itbl infoTblEnv }
110121
return (itbl, rc)
111122
Just itbl -> return (itbl, rc)
112123

113-
pauseDebuggee :: Debuggee -> IO a -> IO a
114-
pauseDebuggee d =
115-
bracket_ (void $ request d RequestPause) (void $ request d RequestResume)
124+
pauseDebuggee :: DebuggeeAction a -> DebuggeeAction a
125+
pauseDebuggee action = do
126+
-- TODO: replace poor-mans bracket_ with proper implementation for StateT
127+
request RequestPause
128+
rc <- action
129+
request RequestResume
130+
return rc
116131

117132
getDwarfInfo :: FilePath -> IO Dwarf
118133
getDwarfInfo fn = do
@@ -121,10 +136,12 @@ getDwarfInfo fn = do
121136
-- print $ DwarfPretty.dwarf dwarf
122137
return dwarf
123138

124-
lookupDwarf :: Debuggee -> InfoTablePtr -> Maybe ([FilePath], Int, Int)
125-
lookupDwarf d (InfoTablePtr w) = do
126-
(Dwarf units) <- debuggeeDwarf d
127-
asum (map (lookupDwarfUnit (fromBE64 w)) units)
139+
lookupDwarf :: InfoTablePtr -> DebuggeeAction (Maybe ([FilePath], Int, Int))
140+
lookupDwarf (InfoTablePtr w) = do
141+
mDwarf <- gets debuggeeDwarf
142+
case mDwarf of
143+
Nothing -> return Nothing
144+
Just (Dwarf units) -> return $ asum (map (lookupDwarfUnit (fromBE64 w)) units)
128145

129146
lookupDwarfUnit :: Word64 -> Boxed CompilationUnit -> Maybe ([FilePath], Int, Int)
130147
lookupDwarfUnit w (Boxed _ cu) = do
@@ -158,63 +175,66 @@ lookupDwarfLine w Nothing (d, nd) = do
158175
else Nothing
159176
lookupDwarfLine _ (Just r) _ = Just r
160177

161-
showFileSnippet :: Debuggee -> ([FilePath], Int, Int) -> IO ()
162-
showFileSnippet d (fps, l, c) = go fps
178+
showFileSnippet :: ([FilePath], Int, Int) -> DebuggeeAction ()
179+
showFileSnippet (fps, l, c) = do
180+
dbgFilename <- gets debuggeeFilename
181+
liftIO $ go dbgFilename fps
163182
where
164-
go [] = putStrLn ("No files could be found: " ++ show fps)
165-
go (fp: fps) = do
166-
exists <- doesFileExist fp
183+
go :: FilePath -> [FilePath] -> IO ()
184+
go _ [] = putStrLn ("No files could be found: " ++ show fps)
185+
go dbgFilename (fp:fps) = do
186+
exists <- liftIO $ doesFileExist $ fp
167187
-- get file modtime
168188
if not exists
169-
then go fps
189+
then go dbgFilename fps
170190
else do
171-
fp `warnIfNewer` (debuggeeFilename d)
191+
-- TODO: get the modtime of debuggee above
192+
fp `warnIfNewer` dbgFilename
172193
src <- zip [1..] . lines <$> readFile fp
173194
let ctx = take 10 (drop (max (l - 5) 0) src)
174195
putStrLn (fp <> ":" <> show l <> ":" <> show c)
175196
mapM_ (\(n, l) ->
176197
let sn = show n
177198
in putStrLn (sn <> replicate (5 - length sn) ' ' <> l)) ctx
178199

179-
dereferenceClosure :: Debuggee -> ClosurePtr -> IO Closure
180-
dereferenceClosure d c = head <$> dereferenceClosures d [c]
200+
dereferenceClosure :: ClosurePtr -> DebuggeeAction Closure
201+
dereferenceClosure c = head <$> dereferenceClosures [c]
181202

182-
dereferenceClosures :: Debuggee -> [ClosurePtr] -> IO [Closure]
183-
dereferenceClosures d cs = do
184-
raw_cs <- request d (RequestClosures cs)
203+
dereferenceClosures :: [ClosurePtr] -> DebuggeeAction [Closure]
204+
dereferenceClosures cs = do
205+
raw_cs <- request (RequestClosures cs)
185206
let its = map getInfoTblPtr raw_cs
186207
--print $ map (lookupDwarf d) its
187-
raw_its <- request d (RequestInfoTables its)
208+
raw_its <- request (RequestInfoTables its)
188209
return $ map (uncurry decodeClosure) (zip raw_its (zip cs raw_cs))
189210

190-
dereferenceStack :: Debuggee -> StackCont -> IO Stack
191-
dereferenceStack d (StackCont stack) = do
192-
print stack
193-
i <- lookupInfoTable d (coerce stack)
211+
dereferenceStack :: StackCont -> DebuggeeAction Stack
212+
dereferenceStack (StackCont stack) = do
213+
liftIO $ print stack
214+
i <- lookupInfoTable (coerce stack)
194215
let st_it = decodeInfoTable . fst $ i
195-
print i
196-
print st_it
197-
bt <- request d (RequestBitmap (getInfoTblPtr (coerce stack)))
216+
liftIO $ print i
217+
liftIO $ print st_it
218+
bt <- request (RequestBitmap (getInfoTblPtr (coerce stack)))
198219
let decoded_stack = decodeStack stack st_it bt
199-
print decoded_stack
220+
liftIO $ print decoded_stack
200221
return decoded_stack
201222

202-
dereferenceConDesc :: Debuggee -> ClosurePtr -> IO ConstrDesc
203-
dereferenceConDesc d i = do
204-
request d (RequestConstrDesc i)
223+
dereferenceConDesc :: ClosurePtr -> DebuggeeAction ConstrDesc
224+
dereferenceConDesc i = request (RequestConstrDesc i)
205225

206226

207-
fullTraversal :: Debuggee -> ClosurePtr -> IO UClosure
208-
fullTraversal d c = do
209-
dc <- dereferenceClosure d c
210-
print dc
211-
MkFix1 <$> tritraverse (dereferenceConDesc d) (fullStackTraversal d) (fullTraversal d) dc
227+
fullTraversal :: ClosurePtr -> DebuggeeAction UClosure
228+
fullTraversal c = do
229+
dc <- dereferenceClosure c
230+
liftIO $ print dc
231+
MkFix1 <$> tritraverse dereferenceConDesc fullStackTraversal fullTraversal dc
212232

213-
fullStackTraversal :: Debuggee -> StackCont -> IO UStack
214-
fullStackTraversal d sc = do
215-
ds <- dereferenceStack d sc
216-
print ds
217-
MkFix2 <$> traverse (fullTraversal d) ds
233+
fullStackTraversal :: StackCont -> DebuggeeAction UStack
234+
fullStackTraversal sc = do
235+
ds <- dereferenceStack sc
236+
liftIO $ print ds
237+
MkFix2 <$> traverse fullTraversal ds
218238

219239
-- | Print a warning if source file (first argument) is newer than the binary (second argument)
220240
warnIfNewer :: FilePath -> FilePath -> IO ()

ghc-vis/src/GHC/Vis.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,9 @@ react dbg window canvas = do
475475

476476
derefBox :: Debuggee -> DerefFunction
477477
derefBox dbg cp = do
478-
c <- dereferenceClosure dbg cp
479-
tritraverse (dereferenceConDesc dbg) pure pure c
478+
let apply = applyDebuggeeAction dbg
479+
c <- apply $ dereferenceClosure cp
480+
tritraverse (\x -> apply $ dereferenceConDesc x) pure pure c
480481

481482
runCorrect :: MonadIO m => (View -> f) -> m f
482483
runCorrect f = do

stub/Test.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ main :: IO ()
2727
main = do
2828
start
2929
let !y = Data.Sequence.fromList [1..5]
30-
-- let !y = [1..5]
30+
let !y = [1..5]
3131
performGC
3232
saveClosures [Box y]
3333
print "start"

0 commit comments

Comments
 (0)