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"
|