Changes between Version 7 and Version 8 of GhciDebugger


Ignore:
Timestamp:
Oct 25, 2006 1:41:41 PM (9 years ago)
Author:
mnislaih
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GhciDebugger

    v7 v8  
    149149=== Default HValues for the Jump functions ===
    150150The dynamic linker has been modified so that it won't panic if one of the jump functions fails to resolve.
    151 Now, if the dynamic linker fails to find a HValue for a Name, before looking for a static symbol it will ask
     151Now if the dynamic linker fails to find a HValue for a Name, before looking for a static symbol it will ask
    152152{{{
    153153DsBreakpoint.lookupBogusBreakpointVal :: Name -> Maybe HValue
     
    158158
    159159Why didn't I address the problem by forbidding breakpoints inside TH code? I couldn't find an easy solution for this, considering the user is free to put a manual breakpoint wherever.
     160
    160161Why did I introduce the default as a special case in the linker?
     162
    161163I considered other options:
    162164 * Running TH splices in an extended link env. This would probably scatter breakpoint related code deep in the typechecker, and is ugly.
     
    175177The instrumentation is done at the desugarer too, which has been extended accordingly. We distinguish between 'auto' breakpoints, those introduced by the desugarer, and 'normal' breakpoints user created by using the `breakpoint` function directly.
    176178
    177 == The D in Dynamic Breakpoints ==
    178 When we instrument the code we insert a flavor of regular breakpoints which know about their site number. So when one of these is hit, ghci finds out whether that site is enabled and acts accordingly.
    179 GHCi thus stores a boolean matrix of enabled breakpoint sites. This scheme is realized in [http://darcs.haskell.org/SoC/ghc.debugger/compiler/main/Breakpoints.hs Breakpoints.hs]:
    180 {{{
    181 data BkptTable a  = BkptTable {
    182      breakpoints :: Map.Map a (UArray Int Bool)  -- *An array of breaks, indexed by site number
    183    , sites       :: Map.Map a [[(SiteNumber, Int)]] -- *A list of lines, each line can have zero or more sites, which are annotated with a column number
    184    }
    185 }}}
    186 
    187 Since this structure needs to be accessed every time a breakpoint is hit and is modified extremely few times in comparison, the goal is to have as fast access time as possible. Most of the overhead is due to this structure.
    188 It's too bad that I haven't explored alternative designs. (Using bits instead of Bools in the matrix? discard the matrix thing and use an IORef in every breakpoint? some clever trick using the FFI?).
    189 
    190179== Overhead ==
    191180The instrumentation scheme potentially introduces overhead at two stages: compile-time and run-time. Compile-time overhead is unnoticeable for general programs, although there are no benchmarks available to sustain this claim. Run-time overhead is much more noticeable.
     
    199188
    200189GHCi would keep breakpoints disabled until the user defines the first breakpoint, and thus for normal use we could keep the -fdebugging flag enabled always.
     190
    201191The problem is that to make the implementation of `disableAutoBreakpoints` (`enableAutoBreakpoints resp.)  effective at all we need to implement it by relinking the `breakpointJumpAuto` function to a new "do nothing" lambda (to the user-set bkptHandler resp.).
     192
    202193This would imply a relink, which is quite annoying to a user of GHCi since any top level bindings are lost. This is why this functionality is only a proof of concept and is disabled for now. I wish I had a better understanding of how the dynamic linker and the top level environment in ghci work.
    203194
     
    215206== Passing the sitelist of a module around ==
    216207''summarize the modifications made to thread the site list of a module from the renamer to the ghc-api''
     208
    217209TcGblEnv is extended with a dictionary of sites and coordinates (TODO: switch the coordinate datatype to the ghc-standard SrcLoc) introduced in the module at the desugarer.
    218210
     
    240232{{{
    241233data BkptHandler a = BkptHandler {
    242      handleBreakpoint  :: forall b. Session -> [(Id,HValue)] -> BkptLocation a ->  String -> b -> IO b
    243    , isAutoBkptEnabled :: Session -> BkptLocation a -> IO Bool
     234     -- | What to do once an enabled breakpoint is found
     235     handleBreakpoint  :: forall b. Session
     236                                  -> [(Id,HValue)]        -- * Local bindings and their id's
     237                                  -> BkptLocation a    -- * Module and Site #
     238                                  ->  String                 -- * A SrcLoc string msg
     239                                  -> b                         -- * The arg. to the breakpoint fun
     240                                  -> IO b
     241     -- | Implementors should return True if the breakpoint is enabled
     242   , isAutoBkptEnabled :: Session
     243                                -> BkptLocation a      -- * Module and Site #
     244                                -> IO Bool
    244245   }
    245246}}}
    246 '' to be finished''
    247 
     247
     248The Ghci debugger is a client of this API as described below.
     249
     250== The D in Dynamic Breakpoints ==
     251
     252In order to implement the 'isAutoBkptEnabled' record, when a breakpoint is hit GHCi must find out whether that site is enabled or not. GHCi thus stores a boolean matrix of enabled breakpoint sites. This scheme is realized in [http://darcs.haskell.org/SoC/ghc.debugger/compiler/main/Breakpoints.hs Breakpoints.hs]:
     253{{{
     254data BkptTable a  = BkptTable {
     255     breakpoints :: Map.Map a (UArray Int Bool)  -- *An array of breaks, indexed by site number
     256   , sites       :: Map.Map a [[(SiteNumber, Int)]] -- *A list of lines, each line can have zero or more sites, which are annotated with a column number
     257   }
     258}}}
     259
     260Since this structure needs to be accessed every time a breakpoint is hit and is modified extremely few times in comparison, the goal is to have as fast access time as possible. All of the overhead in our debugger is going to be caused by this operation.
     261
     262It's too bad that I haven't explored alternative designs. (Using bits instead of Bools in the matrix? discard the matrix thing and use an IORef in every breakpoint? some clever trick using the FFI?).
    248263
    249264= Pending work =