Rodrigo Mesquita pushed to branch wip/romes/step-out-8 at Glasgow Haskell Compiler / GHC
Commits:
-
95a87614
by Rodrigo Mesquita at 2025-06-30T10:54:35+01:00
-
3a0a3099
by Rodrigo Mesquita at 2025-06-30T11:29:24+01:00
7 changed files:
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/Driver/Session/Inspect.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Eval/Types.hs
- ghc/GHCi/UI.hs
Changes:
... | ... | @@ -178,7 +178,7 @@ assert_modules_match ibi_mod imbs_mod = |
178 | 178 | <+> text "with an InternalBreakpointId for module" <+> ppr ibi_mod)
|
179 | 179 | |
180 | 180 | --------------------------------------------------------------------------------
|
181 | - |
|
181 | +-- Tick-level Breakpoint information
|
|
182 | 182 | --------------------------------------------------------------------------------
|
183 | 183 | |
184 | 184 | -- | Get the source span for this breakpoint
|
... | ... | @@ -92,7 +92,7 @@ data ModuleInfo = ModuleInfo { |
92 | 92 | minf_instances :: [ClsInst],
|
93 | 93 | minf_iface :: Maybe ModIface,
|
94 | 94 | minf_safe :: SafeHaskellMode,
|
95 | - minf_modBreaks :: Maybe (InternalModBreaks, ModBreaks)
|
|
95 | + minf_modBreaks :: Maybe InternalModBreaks
|
|
96 | 96 | }
|
97 | 97 | -- We don't want HomeModInfo here, because a ModuleInfo applies
|
98 | 98 | -- to package modules too.
|
... | ... | @@ -150,8 +150,8 @@ getHomeModuleInfo hsc_env mdl = |
150 | 150 | -- NB: already forced. See Note [Forcing GREInfo] in GHC.Types.GREInfo.
|
151 | 151 | minf_instances = instEnvElts $ md_insts details,
|
152 | 152 | minf_iface = Just iface,
|
153 | - minf_safe = getSafeMode $ mi_trust iface
|
|
154 | - ,minf_modBreaks = getModBreaks hmi
|
|
153 | + minf_safe = getSafeMode $ mi_trust iface,
|
|
154 | + minf_modBreaks = getModBreaks hmi
|
|
155 | 155 | }))
|
156 | 156 | |
157 | 157 | -- | The list of top-level entities defined in a module
|
... | ... | @@ -197,6 +197,6 @@ modInfoIface = minf_iface |
197 | 197 | modInfoSafe :: ModuleInfo -> SafeHaskellMode
|
198 | 198 | modInfoSafe = minf_safe
|
199 | 199 | |
200 | -modInfoModBreaks :: ModuleInfo -> Maybe (InternalModBreaks, ModBreaks)
|
|
200 | +modInfoModBreaks :: ModuleInfo -> Maybe InternalModBreaks
|
|
201 | 201 | modInfoModBreaks = minf_modBreaks
|
202 | 202 |
... | ... | @@ -28,6 +28,7 @@ module GHC.Linker.Loader |
28 | 28 | , extendLoadedEnv
|
29 | 29 | , deleteFromLoadedEnv
|
30 | 30 | -- * Internals
|
31 | + , allocateBreakArrays
|
|
31 | 32 | , rmDupLinkables
|
32 | 33 | , modifyLoaderState
|
33 | 34 | , initLinkDepsOpts
|
... | ... | @@ -705,12 +706,12 @@ loadDecls interp hsc_env span linkable = do |
705 | 706 | allocateBreakArrays
|
706 | 707 | interp
|
707 | 708 | (breakarray_env le)
|
708 | - (catMaybes $ map bc_breaks cbcs)
|
|
709 | + (map bc_breaks cbcs)
|
|
709 | 710 | le2_ccs_env <-
|
710 | 711 | allocateCCS
|
711 | 712 | interp
|
712 | 713 | (ccs_env le)
|
713 | - (catMaybes $ map bc_breaks cbcs)
|
|
714 | + (map bc_breaks cbcs)
|
|
714 | 715 | let le2 = le { itbl_env = le2_itbl_env
|
715 | 716 | , addr_env = le2_addr_env
|
716 | 717 | , breakarray_env = le2_breakarray_env
|
... | ... | @@ -938,8 +939,8 @@ dynLinkBCOs interp pls bcos = do |
938 | 939 | le1 = linker_env pls
|
939 | 940 | ie2 <- linkITbls interp (itbl_env le1) (concatMap bc_itbls cbcs)
|
940 | 941 | ae2 <- foldlM (\env cbc -> allocateTopStrings interp (bc_strs cbc) env) (addr_env le1) cbcs
|
941 | - be2 <- allocateBreakArrays interp (breakarray_env le1) (catMaybes $ map bc_breaks cbcs)
|
|
942 | - ce2 <- allocateCCS interp (ccs_env le1) (catMaybes $ map bc_breaks cbcs)
|
|
942 | + be2 <- allocateBreakArrays interp (breakarray_env le1) (map bc_breaks cbcs)
|
|
943 | + ce2 <- allocateCCS interp (ccs_env le1) (map bc_breaks cbcs)
|
|
943 | 944 | let le2 = le1 { itbl_env = ie2, addr_env = ae2, breakarray_env = be2, ccs_env = ce2 }
|
944 | 945 | |
945 | 946 | names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs
|
... | ... | @@ -1662,15 +1663,19 @@ allocateTopStrings interp topStrings prev_env = do |
1662 | 1663 | allocateBreakArrays ::
|
1663 | 1664 | Interp ->
|
1664 | 1665 | ModuleEnv (ForeignRef BreakArray) ->
|
1665 | - [(InternalModBreaks, ModBreaks)] ->
|
|
1666 | + [InternalModBreaks] ->
|
|
1666 | 1667 | IO (ModuleEnv (ForeignRef BreakArray))
|
1667 | 1668 | allocateBreakArrays interp =
|
1668 | 1669 | foldlM
|
1669 | - ( \be0 (imbs, _mbs) -> do
|
|
1670 | + ( \be0 imbs -> do
|
|
1670 | 1671 | let bi = imodBreaks_breakInfo imbs
|
1671 | - (hi, _) = IM.findMax bi -- allocate as many slots as internal breakpoints
|
|
1672 | - breakArray <- GHCi.newBreakArray interp hi
|
|
1673 | - evaluate $ extendModuleEnv be0 (imodBreaks_module imbs) breakArray
|
|
1672 | + hi = maybe 0 fst (IM.lookupMax bi) -- allocate as many slots as internal breakpoints
|
|
1673 | + if not $ elemModuleEnv (imodBreaks_module imbs) be0 then do
|
|
1674 | + -- If no BreakArray is assigned to this module yet, create one
|
|
1675 | + breakArray <- GHCi.newBreakArray interp hi
|
|
1676 | + evaluate $ extendModuleEnv be0 (imodBreaks_module imbs) breakArray
|
|
1677 | + else
|
|
1678 | + return be0
|
|
1674 | 1679 | )
|
1675 | 1680 | |
1676 | 1681 | -- | Given a list of 'InternalModBreaks' and 'ModBreaks' collected from a list
|
... | ... | @@ -1684,42 +1689,48 @@ allocateBreakArrays interp = |
1684 | 1689 | allocateCCS ::
|
1685 | 1690 | Interp ->
|
1686 | 1691 | ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)) ->
|
1687 | - [(InternalModBreaks, ModBreaks)] ->
|
|
1692 | + [InternalModBreaks] ->
|
|
1688 | 1693 | IO (ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)))
|
1689 | 1694 | allocateCCS interp ce mbss
|
1690 | 1695 | | interpreterProfiled interp = do
|
1691 | 1696 | -- First construct the CCSs for each module, using the 'ModBreaks'
|
1692 | 1697 | ccs_map <- foldlM
|
1693 | - ( \(ccs_map :: ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre))) (_, mbs) -> do
|
|
1694 | - ccs <-
|
|
1695 | - mkCostCentres
|
|
1696 | - interp
|
|
1697 | - (moduleNameString $ moduleName $ modBreaks_module mbs)
|
|
1698 | - (elems $ modBreaks_ccs mbs)
|
|
1699 | - evaluate $
|
|
1700 | - extendModuleEnv ccs_map (modBreaks_module mbs) $
|
|
1701 | - listArray (0, length ccs - 1) ccs
|
|
1698 | + ( \(ccs_map :: ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre))) imbs -> do
|
|
1699 | + case imodBreaks_modBreaks imbs of
|
|
1700 | + Nothing -> return ccs_map -- don't add it
|
|
1701 | + Just mbs -> do
|
|
1702 | + ccs <-
|
|
1703 | + mkCostCentres
|
|
1704 | + interp
|
|
1705 | + (moduleNameString $ moduleName $ modBreaks_module mbs)
|
|
1706 | + (elems $ modBreaks_ccs mbs)
|
|
1707 | + evaluate $
|
|
1708 | + extendModuleEnv ccs_map (modBreaks_module mbs) $
|
|
1709 | + listArray (0, length ccs - 1) ccs
|
|
1702 | 1710 | ) emptyModuleEnv mbss
|
1703 | 1711 | -- Now, construct an array indexed by an 'InternalBreakpointId' index by first
|
1704 | 1712 | -- finding the matching 'BreakpointId' and then looking it up in the ccs_map
|
1705 | 1713 | foldlM
|
1706 | - ( \ce0 (imbs, _) -> do
|
|
1714 | + ( \ce0 imbs -> do
|
|
1707 | 1715 | let breakModl = imodBreaks_module imbs
|
1708 | 1716 | breakInfoMap = imodBreaks_breakInfo imbs
|
1709 | - (hi, _) = IM.findMax breakInfoMap -- as many slots as internal breaks
|
|
1717 | + hi = maybe 0 fst (IM.lookupMax breakInfoMap) -- as many slots as internal breaks
|
|
1710 | 1718 | ccss = expectJust $ lookupModuleEnv ccs_map breakModl
|
1711 | 1719 | ccs_im <- foldlM
|
1712 | 1720 | (\(bids :: IM.IntMap (RemotePtr CostCentre)) cgi -> do
|
1713 | 1721 | let tickBreakId = bi_tick_index $ cgb_tick_id cgi
|
1714 | 1722 | pure $ IM.insert tickBreakId (ccss ! tickBreakId) bids
|
1715 | 1723 | ) mempty breakInfoMap
|
1716 | - evaluate $
|
|
1717 | - extendModuleEnv ce0 breakModl $
|
|
1718 | - listArray (0, hi-1) $
|
|
1719 | - map (\i -> case IM.lookup i ccs_im of
|
|
1720 | - Nothing -> toRemotePtr nullPtr
|
|
1721 | - Just ccs -> ccs
|
|
1722 | - ) [0..hi-1]
|
|
1724 | + if not $ elemModuleEnv breakModl ce0 then do
|
|
1725 | + evaluate $
|
|
1726 | + extendModuleEnv ce0 breakModl $
|
|
1727 | + listArray (0, hi-1) $
|
|
1728 | + map (\i -> case IM.lookup i ccs_im of
|
|
1729 | + Nothing -> toRemotePtr nullPtr
|
|
1730 | + Just ccs -> ccs
|
|
1731 | + ) [0..hi-1]
|
|
1732 | + else
|
|
1733 | + return ce0
|
|
1723 | 1734 | )
|
1724 | 1735 | ce
|
1725 | 1736 | mbss
|
... | ... | @@ -17,6 +17,7 @@ import qualified Data.List.NonEmpty as NE |
17 | 17 | import qualified Data.Semigroup as S
|
18 | 18 | |
19 | 19 | import GHC.HsToCore.Breakpoints
|
20 | +import GHC.ByteCode.Breakpoints
|
|
20 | 21 | import GHC.Driver.Env
|
21 | 22 | import GHC.Driver.Monad
|
22 | 23 | import GHC.Driver.Session.Inspect
|
... | ... | @@ -196,7 +197,7 @@ type TickArray = Array Int [(BreakTickIndex,RealSrcSpan)] |
196 | 197 | makeModuleLineMap :: GhcMonad m => Module -> m (Maybe TickArray)
|
197 | 198 | makeModuleLineMap m = do
|
198 | 199 | mi <- getModuleInfo m
|
199 | - return $ mkTickArray . assocs . modBreaks_locs <$> (fmap snd . modInfoModBreaks =<< mi)
|
|
200 | + return $ mkTickArray . assocs . modBreaks_locs <$> (imodBreaks_modBreaks =<< modInfoModBreaks =<< mi)
|
|
200 | 201 | where
|
201 | 202 | mkTickArray :: [(BreakTickIndex, SrcSpan)] -> TickArray
|
202 | 203 | mkTickArray ticks
|
... | ... | @@ -210,7 +211,7 @@ makeModuleLineMap m = do |
210 | 211 | getModBreak :: GhcMonad m => Module -> m (Maybe ModBreaks)
|
211 | 212 | getModBreak m = do
|
212 | 213 | mod_info <- fromMaybe (panic "getModBreak") <$> getModuleInfo m
|
213 | - pure $ snd <$> modInfoModBreaks mod_info
|
|
214 | + pure $ imodBreaks_modBreaks =<< modInfoModBreaks mod_info
|
|
214 | 215 | |
215 | 216 | --------------------------------------------------------------------------------
|
216 | 217 | -- Getting current breakpoint information
|
... | ... | @@ -237,6 +238,6 @@ getCurrentBreakModule = do |
237 | 238 | return $ case resumes of
|
238 | 239 | [] -> Nothing
|
239 | 240 | (r:_) -> case resumeHistoryIx r of
|
240 | - 0 -> bi_tick_mod . fst <$> resumeBreakpointId r
|
|
241 | + 0 -> ibi_info_mod <$> resumeBreakpointId r
|
|
241 | 242 | ix -> Just $ getHistoryModule $ resumeHistory r !! (ix-1)
|
242 | 243 |
... | ... | @@ -127,13 +127,11 @@ import GHC.Tc.Utils.Instantiate (instDFunType) |
127 | 127 | import GHC.Tc.Utils.Monad
|
128 | 128 | |
129 | 129 | import GHC.IfaceToCore
|
130 | -import GHC.HsToCore.Breakpoints
|
|
130 | +import GHC.ByteCode.Breakpoints
|
|
131 | 131 | |
132 | 132 | import Control.Monad
|
133 | -import Data.Array
|
|
134 | 133 | import Data.Dynamic
|
135 | 134 | import Data.IntMap (IntMap)
|
136 | -import qualified Data.IntMap as IntMap
|
|
137 | 135 | import Data.List (find,intercalate)
|
138 | 136 | import Data.List.NonEmpty (NonEmpty)
|
139 | 137 | import Unsafe.Coerce ( unsafeCoerce )
|
... | ... | @@ -146,26 +144,28 @@ import GHCi.BreakArray (BreakArray) |
146 | 144 | getResumeContext :: GhcMonad m => m [Resume]
|
147 | 145 | getResumeContext = withSession (return . ic_resume . hsc_IC)
|
148 | 146 | |
149 | -mkHistory :: HUG.HomeUnitGraph -> ForeignHValue -> BreakpointId -> InternalBreakpointId -> IO History
|
|
150 | -mkHistory hug hval bid ibi = History hval bid ibi <$> findEnclosingDecls hug bid
|
|
147 | +mkHistory :: HUG.HomeUnitGraph -> ForeignHValue -> InternalBreakpointId -> IO History
|
|
148 | +mkHistory hug hval ibi = History hval ibi <$> findEnclosingDecls hug ibi
|
|
151 | 149 | |
152 | 150 | getHistoryModule :: History -> Module
|
153 | -getHistoryModule = bi_tick_mod . historyBreakpointId
|
|
151 | +getHistoryModule = ibi_info_mod . historyBreakpointId
|
|
154 | 152 | |
155 | 153 | getHistorySpan :: HUG.HomeUnitGraph -> History -> IO SrcSpan
|
156 | 154 | getHistorySpan hug hist = do
|
157 | - let bid = historyBreakpointId hist
|
|
158 | - (_, brks) <- readModBreaks hug (bi_tick_mod bid)
|
|
159 | - return $ getBreakLoc bid brks
|
|
155 | + let ibi = historyBreakpointId hist
|
|
156 | + brks <- expectJust <$> readModBreaks hug ibi
|
|
157 | + return $ expectJust $ getBreakLoc ibi brks
|
|
160 | 158 | |
161 | 159 | {- | Finds the enclosing top level function name -}
|
162 | 160 | -- ToDo: a better way to do this would be to keep hold of the decl_path computed
|
163 | 161 | -- by the coverage pass, which gives the list of lexically-enclosing bindings
|
164 | 162 | -- for each tick.
|
165 | -findEnclosingDecls :: HUG.HomeUnitGraph -> BreakpointId -> IO [String]
|
|
166 | -findEnclosingDecls hug bid = do
|
|
167 | - (_, brks) <- readModBreaks hug (bi_tick_mod bid)
|
|
168 | - return $ modBreaks_decls brks ! bi_tick_index bid
|
|
163 | +findEnclosingDecls :: HUG.HomeUnitGraph -> InternalBreakpointId -> IO [String]
|
|
164 | +findEnclosingDecls hug ibi = do
|
|
165 | + readModBreaks hug ibi >>= \case
|
|
166 | + Nothing -> return []
|
|
167 | + Just brks -> return $
|
|
168 | + fromMaybe [] (getBreakDecls ibi brks)
|
|
169 | 169 | |
170 | 170 | -- | Update fixity environment in the current interactive context.
|
171 | 171 | updateFixityEnv :: GhcMonad m => FixityEnv -> m ()
|
... | ... | @@ -353,12 +353,11 @@ handleRunStatus step expr bindings final_ids status history0 = do |
353 | 353 | let hug = hsc_HUG hsc_env
|
354 | 354 | let ibi@InternalBreakpointId{ibi_info_index}
|
355 | 355 | = evalBreakpointToId eval_break
|
356 | - bid <- liftIO $ internalBreakIdToBreakId hug ibi
|
|
357 | - (_, tick_brks) <- liftIO $ readModBreaks hug (bi_tick_mod bid)
|
|
358 | - breakArray <- getBreakArray interp ibi
|
|
356 | + brks <- liftIO $ readModBreaks hug ibi
|
|
357 | + breakArray <- getBreakArray interp ibi (expectJust brks)
|
|
359 | 358 | let
|
360 | - span = getBreakLoc bid tick_brks
|
|
361 | - decl = intercalate "." $ modBreaks_decls tick_brks ! bi_tick_index bid
|
|
359 | + span = fromMaybe noSrcSpan $ getBreakLoc ibi =<< brks
|
|
360 | + decl = intercalate "." $ fromMaybe [] $ getBreakDecls ibi =<< brks
|
|
362 | 361 | |
363 | 362 | -- Was this breakpoint explicitly enabled (ie. in @BreakArray@)?
|
364 | 363 | bactive <- liftIO $ breakpointStatus interp breakArray ibi_info_index
|
... | ... | @@ -381,7 +380,7 @@ handleRunStatus step expr bindings final_ids status history0 = do |
381 | 380 | , resumeBindings = bindings
|
382 | 381 | , resumeFinalIds = final_ids
|
383 | 382 | , resumeApStack = apStack_fhv
|
384 | - , resumeBreakpointId = Just (bid, ibi)
|
|
383 | + , resumeBreakpointId = Just ibi
|
|
385 | 384 | , resumeSpan = span
|
386 | 385 | , resumeHistory = toListBL history0
|
387 | 386 | , resumeDecl = decl
|
... | ... | @@ -396,7 +395,7 @@ handleRunStatus step expr bindings final_ids status history0 = do |
396 | 395 | let eval_opts = initEvalOpts dflags (enableGhcStepMode step)
|
397 | 396 | status <- liftIO $ GHCi.resumeStmt interp eval_opts resume_ctxt_fhv
|
398 | 397 | history <- if not tracing then pure history0 else do
|
399 | - history1 <- liftIO $ mkHistory hug apStack_fhv bid ibi
|
|
398 | + history1 <- liftIO $ mkHistory hug apStack_fhv ibi
|
|
400 | 399 | let !history' = history1 `consBL` history0
|
401 | 400 | -- history is strict, otherwise our BoundedList is pointless.
|
402 | 401 | return history'
|
... | ... | @@ -449,7 +448,7 @@ resumeExec step mbCnt |
449 | 448 | -- When the user specified a break ignore count, set it
|
450 | 449 | -- in the interpreter
|
451 | 450 | case (mb_brkpt, mbCnt) of
|
452 | - (Just (_bid, ibi), Just cnt) ->
|
|
451 | + (Just ibi, Just cnt) ->
|
|
453 | 452 | setupBreakpoint interp ibi cnt
|
454 | 453 | _ -> return ()
|
455 | 454 | |
... | ... | @@ -459,24 +458,35 @@ resumeExec step mbCnt |
459 | 458 | hug = hsc_HUG hsc_env
|
460 | 459 | hist' = case mb_brkpt of
|
461 | 460 | Nothing -> pure prevHistoryLst
|
462 | - Just (bid, ibi)
|
|
461 | + Just ibi
|
|
463 | 462 | | breakHere False step span -> do
|
464 | - hist1 <- liftIO (mkHistory hug apStack bid ibi)
|
|
463 | + hist1 <- liftIO (mkHistory hug apStack ibi)
|
|
465 | 464 | return $ hist1 `consBL` fromListBL 50 hist
|
466 | 465 | | otherwise -> pure prevHistoryLst
|
467 | 466 | handleRunStatus step expr bindings final_ids status =<< hist'
|
468 | 467 | |
469 | 468 | setupBreakpoint :: GhcMonad m => Interp -> InternalBreakpointId -> Int -> m () -- #19157
|
470 | 469 | setupBreakpoint interp ibi cnt = do
|
471 | - breakArray <- getBreakArray interp ibi
|
|
470 | + hug <- hsc_HUG <$> getSession
|
|
471 | + ims <- liftIO $ readModBreaks hug ibi
|
|
472 | + breakArray <- getBreakArray interp ibi (expectJust ims)
|
|
472 | 473 | liftIO $ GHCi.storeBreakpoint interp breakArray (ibi_info_index ibi) cnt
|
473 | 474 | |
474 | -getBreakArray :: GhcMonad m => Interp -> InternalBreakpointId -> m (ForeignRef BreakArray)
|
|
475 | -getBreakArray interp InternalBreakpointId{ibi_info_mod} = do
|
|
476 | - breakArrays <- liftIO $ breakarray_env . linker_env . expectJust
|
|
477 | - <$> Loader.getLoaderState interp
|
|
478 | - pprTraceM "hello" (ppr $ moduleEnvKeys breakArrays)
|
|
479 | - return $ expectJust $ lookupModuleEnv breakArrays ibi_info_mod
|
|
475 | +getBreakArray :: GhcMonad m => Interp -> InternalBreakpointId -> InternalModBreaks -> m (ForeignRef BreakArray)
|
|
476 | +getBreakArray interp InternalBreakpointId{ibi_info_mod} imbs = do
|
|
477 | + |
|
478 | + liftIO $ modifyLoaderState interp $ \ld_st -> do
|
|
479 | + let le = linker_env ld_st
|
|
480 | + |
|
481 | + -- Recall that BreakArrays are allocated only at BCO link time, so if we
|
|
482 | + -- haven't linked the BCOs we intend to break at yet, we allocate the arrays here.
|
|
483 | + ba_env <- allocateBreakArrays interp (breakarray_env le) [imbs]
|
|
484 | + |
|
485 | + return
|
|
486 | + ( ld_st { linker_env = le{breakarray_env = ba_env} }
|
|
487 | + , expectJust {- just computed -} $
|
|
488 | + lookupModuleEnv ba_env ibi_info_mod
|
|
489 | + )
|
|
480 | 490 | |
481 | 491 | back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
|
482 | 492 | back n = moveHist (+n)
|
... | ... | @@ -504,11 +514,11 @@ moveHist fn = do |
504 | 514 | update_ic apStack mb_info = do
|
505 | 515 | span <- case mb_info of
|
506 | 516 | Nothing -> return $ mkGeneralSrcSpan (fsLit "<unknown>")
|
507 | - Just (bid, _ibi) -> liftIO $ do
|
|
508 | - (_, brks) <- readModBreaks (hsc_HUG hsc_env) (bi_tick_mod bid)
|
|
509 | - return $ getBreakLoc bid brks
|
|
517 | + Just ibi -> liftIO $ do
|
|
518 | + brks <- readModBreaks (hsc_HUG hsc_env) ibi
|
|
519 | + return $ fromMaybe noSrcSpan $ getBreakLoc ibi =<< brks
|
|
510 | 520 | (hsc_env1, names) <-
|
511 | - liftIO $ bindLocalsAtBreakpoint hsc_env apStack span (snd <$> mb_info)
|
|
521 | + liftIO $ bindLocalsAtBreakpoint hsc_env apStack span mb_info
|
|
512 | 522 | let ic = hsc_IC hsc_env1
|
513 | 523 | r' = r { resumeHistoryIx = new_ix }
|
514 | 524 | ic' = ic { ic_resume = r':rs }
|
... | ... | @@ -527,7 +537,7 @@ moveHist fn = do |
527 | 537 | update_ic apStack mb_brkpt
|
528 | 538 | else case history !! (new_ix - 1) of
|
529 | 539 | History{..} ->
|
530 | - update_ic historyApStack (Just (historyBreakpointId, historyInternalBreakpointId))
|
|
540 | + update_ic historyApStack (Just historyBreakpointId)
|
|
531 | 541 | |
532 | 542 | |
533 | 543 | -- -----------------------------------------------------------------------------
|
... | ... | @@ -567,12 +577,10 @@ bindLocalsAtBreakpoint hsc_env apStack span Nothing = do |
567 | 577 | -- of the breakpoint and the free variables of the expression.
|
568 | 578 | bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
|
569 | 579 | let hug = hsc_HUG hsc_env
|
570 | - (info_brks, _) <- readModBreaks hug (ibi_info_mod ibi)
|
|
571 | - bid <- internalBreakIdToBreakId hug ibi
|
|
572 | - (_, tick_brks) <- readModBreaks hug (bi_tick_mod bid)
|
|
573 | - let info = expectJust $ IntMap.lookup (ibi_info_index ibi) (imodBreaks_breakInfo info_brks)
|
|
580 | + info_brks <- readModBreaks hug ibi
|
|
581 | + let info = getInternalBreak ibi (expectJust info_brks)
|
|
574 | 582 | interp = hscInterp hsc_env
|
575 | - occs = modBreaks_vars tick_brks ! bi_tick_index bid
|
|
583 | + occs = fromMaybe [] $ getBreakVars ibi =<< info_brks
|
|
576 | 584 | |
577 | 585 | -- Rehydrate to understand the breakpoint info relative to the current environment.
|
578 | 586 | -- This design is critical to preventing leaks (#22530)
|
... | ... | @@ -176,9 +176,8 @@ data Resume = Resume |
176 | 176 | , resumeFinalIds :: [Id] -- [Id] to bind on completion
|
177 | 177 | , resumeApStack :: ForeignHValue -- The object from which we can get
|
178 | 178 | -- value of the free variables.
|
179 | - , resumeBreakpointId :: Maybe (BreakpointId, InternalBreakpointId)
|
|
179 | + , resumeBreakpointId :: Maybe InternalBreakpointId
|
|
180 | 180 | -- ^ the internal breakpoint we stopped at
|
181 | - -- and a cached computation of BreakpointId from it.
|
|
182 | 181 | -- (Nothing <=> exception)
|
183 | 182 | , resumeSpan :: SrcSpan -- just a copy of the SrcSpan
|
184 | 183 | -- from the ModBreaks,
|
... | ... | @@ -195,9 +194,7 @@ type ResumeBindings = ([TyThing], IcGlobalRdrEnv) |
195 | 194 | |
196 | 195 | data History = History
|
197 | 196 | { historyApStack :: ForeignHValue
|
198 | - , historyBreakpointId :: BreakpointId
|
|
199 | - -- ^ Cache the 'BreakpointId' computed from the 'InternalBreakpointId'
|
|
200 | - , historyInternalBreakpointId :: InternalBreakpointId
|
|
197 | + , historyBreakpointId :: InternalBreakpointId
|
|
201 | 198 | -- ^ internal breakpoint identifier
|
202 | 199 | , historyEnclosingDecls :: [String]
|
203 | 200 | -- ^ declarations enclosing the breakpoint
|
... | ... | @@ -45,6 +45,7 @@ import GHC.Runtime.Eval (mkTopLevEnv) |
45 | 45 | import GHC.Runtime.Eval.Utils
|
46 | 46 | |
47 | 47 | -- The GHC interface
|
48 | +import GHC.ByteCode.Breakpoints (imodBreaks_modBreaks)
|
|
48 | 49 | import GHC.Runtime.Interpreter
|
49 | 50 | import GHCi.RemoteTypes
|
50 | 51 | import GHCi.BreakArray( breakOn, breakOff )
|
... | ... | @@ -1564,7 +1565,6 @@ afterRunStmt :: GhciMonad m => SingleStep {-^ Type of step we took just before - |
1564 | 1565 | -> GHC.ExecResult -> m GHC.ExecResult
|
1565 | 1566 | afterRunStmt step run_result = do
|
1566 | 1567 | resumes <- GHC.getResumeContext
|
1567 | - hug <- hsc_HUG <$> GHC.getSession
|
|
1568 | 1568 | case run_result of
|
1569 | 1569 | GHC.ExecComplete{..} ->
|
1570 | 1570 | case execResult of
|
... | ... | @@ -3793,7 +3793,7 @@ pprStopped res = |
3793 | 3793 | <> text (GHC.resumeDecl res))
|
3794 | 3794 | <> char ',' <+> ppr (GHC.resumeSpan res)
|
3795 | 3795 | where
|
3796 | - mb_mod_name = moduleName . ibi_info_mod . snd <$> GHC.resumeBreakpointId res
|
|
3796 | + mb_mod_name = moduleName . ibi_info_mod <$> GHC.resumeBreakpointId res
|
|
3797 | 3797 | |
3798 | 3798 | showUnits :: GHC.GhcMonad m => m ()
|
3799 | 3799 | showUnits = mapNonInteractiveHomeUnitsM $ \dflags -> do
|
... | ... | @@ -4448,7 +4448,7 @@ breakById inp = do |
4448 | 4448 | Left sdoc -> printForUser sdoc
|
4449 | 4449 | Right (mod, mod_info, fun_str) -> do
|
4450 | 4450 | let modBreaks = expectJust (GHC.modInfoModBreaks mod_info)
|
4451 | - findBreakAndSet mod $ \_ -> findBreakForBind fun_str (snd modBreaks)
|
|
4451 | + findBreakAndSet mod $ \_ -> maybe [] (findBreakForBind fun_str) (imodBreaks_modBreaks modBreaks)
|
|
4452 | 4452 | |
4453 | 4453 | breakSyntax :: a
|
4454 | 4454 | breakSyntax = throwGhcException $ CmdLineError ("Syntax: :break [<mod>.]<func>[.<func>]\n"
|