Rodrigo Mesquita pushed to branch wip/romes/step-out-8 at Glasgow Haskell Compiler / GHC

Commits:

7 changed files:

Changes:

  • compiler/GHC/ByteCode/Breakpoints.hs
    ... ... @@ -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
    

  • compiler/GHC/Driver/Session/Inspect.hs
    ... ... @@ -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
     

  • compiler/GHC/Linker/Loader.hs
    ... ... @@ -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
    

  • compiler/GHC/Runtime/Debugger/Breakpoints.hs
    ... ... @@ -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
     

  • compiler/GHC/Runtime/Eval.hs
    ... ... @@ -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)
    

  • compiler/GHC/Runtime/Eval/Types.hs
    ... ... @@ -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
    

  • ghc/GHCi/UI.hs
    ... ... @@ -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"