Changes between Version 7 and Version 8 of GhciDebugger


Ignore:
Timestamp:
Oct 25, 2006 1:41:41 PM (7 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 =