Class: Trepan::Core
Overview
This class contains the Trepan core routines, such as an event processor which is responsible of handling what to do when an event is triggered.
See also ‘rdbgr’ the top-level Trepan class and command-line routine which ultimately will call this.
Constant Summary collapse
- STEPPING_EVENT_MASK =
Synchronous events
LINE_EVENT_MASK | CLASS_EVENT_MASK | CALL_EVENT_MASK | RETURN_EVENT_MASK | C_CALL_EVENT_MASK | C_RETURN_EVENT_MASK | INSN_EVENT_MASK | BRKPT_EVENT_MASK | YIELD_EVENT_MASK | LEAVE_EVENT_MASK | SEND_EVENT_MASK
- ASYNC_EVENT_MASK =
RAISE_EVENT_MASK | VM_EVENT_MASK | SWITCH_EVENT_MASK
- CORE_DEFAULT_SETTINGS =
{ :cmdproc_opts => {}, :debug_core_events => false, :hook_name => :event_processor, # or :old_event_processor :step_count => 0, # Stop at next event :async_events => ASYNC_EVENT_MASK, # Not sure what the "right" set really is. The below is just # a guess. Use "set events" or customize in ~/.trepanrc :step_events => # (DEFAULT_EVENT_MASK | INSN_EVENT_MASK) & (DEFAULT_EVENT_MASK ) & ~(C_CALL_EVENT_MASK | C_RETURN_EVENT_MASK | SEND_EVENT_MASK) }
Instance Attribute Summary collapse
-
#async_events ⇒ Object
Returns the value of attribute async_events.
-
#dbgr ⇒ Object
readonly
bitmask of asyncronous events - used all the time.
-
#event ⇒ Object
readonly
Returns the value of attribute event.
-
#event_proc ⇒ Object
readonly
String - event which triggering event processor.
-
#exception ⇒ Object
Returns the value of attribute exception.
-
#frame ⇒ Object
readonly
Return exception to pass back.
-
#hook_arg ⇒ Object
readonly
‘arg’ passed from trace hook.
-
#mutex ⇒ Object
Returns the value of attribute mutex.
-
#processor ⇒ Object
mutex to lock out other threads from entering debugger while we are in it.
-
#settings ⇒ Object
readonly
Hash of things you can configure.
-
#step_count ⇒ Object
Returns the value of attribute step_count.
-
#step_events ⇒ Object
Fixnum.
-
#unmaskable_events ⇒ Object
bitmask of events - used only when we are stepping.
Instance Method Summary collapse
-
#debugger(prev_count = 0) ⇒ Object
Call this from inside the program you want to get a synchronous call to the debugger.
-
#event_processor(event, frame, arg = nil) ⇒ Object
A trace-hook processor with the interface a trace hook should have.
-
#initialize(debugger, settings = {}) ⇒ Core
constructor
A new instance of Core.
-
#old_event_processor(event, file, line, id, bind, klass) ⇒ Object
A Ruby 1.8-style event processor.
- #step_events_list ⇒ Object
-
#trace_var_processor(var_name, value) ⇒ Object
A trace-hook processor for ‘trace var’.
Constructor Details
#initialize(debugger, settings = {}) ⇒ Core
Returns a new instance of Core.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'app/core.rb', line 68 def initialize(debugger, settings={}) @dbgr = debugger @exception = nil @mutex = Mutex.new @settings = CORE_DEFAULT_SETTINGS.merge(settings) @step_count = @settings[:step_count] @step_events = @settings[:step_events] @async_events = @settings[:async_events] @debug_events = @settings[:debug_core_events] hook_name = @settings[:hook_name] @event_proc = self.method(hook_name).to_proc @processor = CmdProcessor.new(self, @settings[:cmdproc_opts]) @unmaskable_events = %w(brkpt raise switch vm) end |
Instance Attribute Details
#async_events ⇒ Object
Returns the value of attribute async_events.
16 17 18 |
# File 'app/core.rb', line 16 def async_events @async_events end |
#dbgr ⇒ Object (readonly)
bitmask of asyncronous events - used all the time
18 19 20 |
# File 'app/core.rb', line 18 def dbgr @dbgr end |
#event ⇒ Object (readonly)
Returns the value of attribute event.
19 20 21 |
# File 'app/core.rb', line 19 def event @event end |
#event_proc ⇒ Object (readonly)
String - event which triggering event processor
21 22 23 |
# File 'app/core.rb', line 21 def event_proc @event_proc end |
#exception ⇒ Object
Returns the value of attribute exception.
22 23 24 |
# File 'app/core.rb', line 22 def exception @exception end |
#frame ⇒ Object (readonly)
Return exception to pass back. A ‘raise’ command can set this.
24 25 26 |
# File 'app/core.rb', line 24 def frame @frame end |
#hook_arg ⇒ Object (readonly)
‘arg’ passed from trace hook
25 26 27 |
# File 'app/core.rb', line 25 def hook_arg @hook_arg end |
#mutex ⇒ Object
Returns the value of attribute mutex.
26 27 28 |
# File 'app/core.rb', line 26 def mutex @mutex end |
#processor ⇒ Object
mutex to lock out other threads from entering debugger while we are in it.
28 29 30 |
# File 'app/core.rb', line 28 def processor @processor end |
#settings ⇒ Object (readonly)
Hash of things you can configure
29 30 31 |
# File 'app/core.rb', line 29 def settings @settings end |
#step_count ⇒ Object
Returns the value of attribute step_count.
30 31 32 |
# File 'app/core.rb', line 30 def step_count @step_count end |
#step_events ⇒ Object
Fixnum. Negative means no tracing, 0 means stop on next event, 1 means ignore one event. Step events gives the kind of things to count as a step.
34 35 36 |
# File 'app/core.rb', line 34 def step_events @step_events end |
#unmaskable_events ⇒ Object
bitmask of events - used only when we are stepping
36 37 38 |
# File 'app/core.rb', line 36 def unmaskable_events @unmaskable_events end |
Instance Method Details
#debugger(prev_count = 0) ⇒ Object
Call this from inside the program you want to get a synchronous call to the debugger. set prev_count to the number of levels before the caller you want to skip.
162 163 164 165 166 167 168 169 |
# File 'app/core.rb', line 162 def debugger(prev_count=0) while @frame && @frame.type == 'IFUNC' @frame = @frame.prev end frame = RubyVM::Frame.current.prev(prev_count+1) @step_count = 0 # Make event processor stop event_processor('debugger-call', frame) end |
#event_processor(event, frame, arg = nil) ⇒ Object
A trace-hook processor with the interface a trace hook should have.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'app/core.rb', line 94 def event_processor(event, frame, arg=nil) return_exception = nil # FIXME: check for breakpoints or other unmaskable events. # For now there are none. @mutex.synchronize do @frame = frame while @frame.type == 'IFUNC' @frame = @frame.prev end if @step_count > 0 @step_count -= 1 break elsif @step_count < 0 && ! @unmaskable_events.member?(event) break end @event = event @hook_arg = arg ### debug: ### puts "#{frame.file[1]}:#{frame.source_location[0]}:in `#{frame.method}' #{event}" # if %w(line).member?(event) @processor.process_commands(@frame) # FIXME: There should be a Trace.event_mask which should return the first # mask that matches the given trace hook. if @step_count < 0 # If we are continuing, no need to stop at stepping events. Trace.event_masks[0] &= ~STEPPING_EVENT_MASK else # Set to trace only those events we are interested in. # Don't step/trace into Ruby routines called from here in the code # below (e.g. "trace_hooks"). step_count_save = step_count @step_count = -1 unless @event_proc == dbgr.trace_filter.hook_proc dbgr.trace_filter.add_trace_func(@event_proc) ## debug: p '+++1', @event_proc, dbgr.trace_filter.hook_proc end # FIXME: this doesn't work. Bug in rb-trace? # Trace.event_masks[0] = @step_events | @async_events RubyVM::TraceHook::trace_hooks[0].event_mask = @step_events | @async_events @step_count = step_count_save end # Nil out variables just in case... return_exception = @exception @frame = @event = @arg = @exception = nil end return return_exception end |
#old_event_processor(event, file, line, id, bind, klass) ⇒ Object
A Ruby 1.8-style event processor. We don’t use file, line, id, bind.
155 156 157 |
# File 'app/core.rb', line 155 def old_event_processor(event, file, line, id, bind, klass) event_processor(event, RubyVM::Frame.current.prev) end |
#step_events_list ⇒ Object
85 86 87 88 89 90 91 |
# File 'app/core.rb', line 85 def step_events_list if 0 == @step_events return nil else Trace.bitmask2events(@step_events).join(', ') end end |
#trace_var_processor(var_name, value) ⇒ Object
A trace-hook processor for ‘trace var’
172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'app/core.rb', line 172 def trace_var_processor(var_name, value) frame = RubyVM::Frame.current.prev(2) if 'CFUNC' == frame.type # Don't need the C call that got us here. prev = frame.prev frame = frame.prev if prev end # Stop future tracing into the debugger Thread.current.tracing = true @step_count = 0 # Make event processor stop event_processor('trace-var', frame, [var_name, value]) end |