Class: Trepan::Core

Inherits:
Object
  • Object
show all
Defined in:
app/core.rb

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 lib/trepanning.rb, the top-level Trepan class, and command-line routine bin/trepan which ultimately will call this.

Constant Summary collapse

STEPPING_EVENTS =

Synchronous events

Set.new([:line, :class, :call, :return, :c_call,
:c_return, :raise, :b_call, :b_return,
:thread_begin, :thread_end, :brkpt])
ASYNC_EVENTS =
Set.new([:raise])
CORE_DEFAULT_SETTINGS =
{
    :cmdproc_opts      => {},
    :debug_core_events => false,
    :hook_name         => :event_processor,
    :step_count        => 0,                # Stop at next event
    :async_events      => ASYNC_EVENTS,

    # Not sure what the "right" set really is. The below is just
    # a guess. Use "set events" or customize in ~/.trepanrc
    :step_events       => STEPPING_EVENTS - [:c_call, :c_return]
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(debugger, settings = {}) ⇒ Core

Returns a new instance of Core.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/core.rb', line 61

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)
    @current_thread = nil
    @top_skip    = 0
    @trace_point = nil
end

Instance Attribute Details

#async_eventsObject

Returns the value of attribute async_events.



16
17
18
# File 'app/core.rb', line 16

def async_events
  @async_events
end

#dbgrObject (readonly)

bitmask of asyncronous events - used all the time



18
19
20
# File 'app/core.rb', line 18

def dbgr
  @dbgr
end

#eventObject (readonly)

Returns the value of attribute event.



19
20
21
# File 'app/core.rb', line 19

def event
  @event
end

#event_procObject (readonly)

String - event which triggering event processor



21
22
23
# File 'app/core.rb', line 21

def event_proc
  @event_proc
end

#exceptionObject

Returns the value of attribute exception.



22
23
24
# File 'app/core.rb', line 22

def exception
  @exception
end

#frameObject (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_argObject (readonly)

‘arg’ passed from trace hook



25
26
27
# File 'app/core.rb', line 25

def hook_arg
  @hook_arg
end

#mutexObject

Returns the value of attribute mutex.



26
27
28
# File 'app/core.rb', line 26

def mutex
  @mutex
end

#processorObject

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

#settingsObject (readonly)

Hash of things you can configure



29
30
31
# File 'app/core.rb', line 29

def settings
  @settings
end

#step_countObject

Returns the value of attribute step_count.



30
31
32
# File 'app/core.rb', line 30

def step_count
  @step_count
end

#step_eventsObject

Returns the value of attribute step_events.



35
36
37
# File 'app/core.rb', line 35

def step_events
  @step_events
end

#top_skipObject

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 top_skip
  @top_skip
end

#trace_pointObject (readonly)

Returns the value of attribute trace_point.



38
39
40
# File 'app/core.rb', line 38

def trace_point
  @trace_point
end

#unmaskable_eventsObject

bitmask of events - used only when we are stepping



37
38
39
# File 'app/core.rb', line 37

def unmaskable_events
  @unmaskable_events
end

Instance Method Details

#event_processor(frame, event, hook_arg = nil) ⇒ Object

A trace-hook processor with the interface a trace hook should have.



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
# File 'app/core.rb', line 102

def event_processor(frame, event, hook_arg=nil)

    return_exception = nil
    # FIXME: check for breakpoints or other unmaskable events.
    # For now there are none.

    return if @mutex.locked? and Thread.current == @current_thread

    @mutex.synchronize do
        @current_thread = Thread.current
        @frame = frame

        if dbgr.trace_filter.member?(@frame.method)
            # puts "Not tracing #{@frame.method}"
            return
         end

        if @step_count > 0
            @step_count -= 1
            break
        elsif @step_count < 0 && ! @unmaskable_events.member?(event.to_s)
            break
        end

        @event    = event
        @hook_arg = hook_arg

        ### debug:
        ### puts "#{frame.file[1]}:#{frame.source_location[0]}:in `#{frame.method}' #{event}"
        # if %w(line).member?(event)
        @processor.process_commands(@frame, top_skip)

        # Nil out variables just in case...

        return_exception = @exception
        @frame = @event = @arg = @exception = nil
        @top_skip = 0
    end
    return return_exception
end

#event_processor_tp(tp) ⇒ Object

A trace-hook processor for tracepoints



90
91
92
93
94
95
96
97
98
99
# File 'app/core.rb', line 90

def event_processor_tp(tp)
    ## FIXME: tracepoint has an arg param. Figure out how to use it.
    @trace_point = tp
    # RubyVM::Frame.get.frame.trace_off = true
    # p @trace_point
    # p @trace_point.event, @trace_point.frame.source_location
    retval = event_processor(tp.frame, tp.event)
    @trace_point = nil
    return retval
end

#step_events_listObject



81
82
83
84
85
86
87
# File 'app/core.rb', line 81

def step_events_list
    if @trace_point
        @trace_point.event_mask
    else
        nil
    end
end

#trace_var_processor(var_name, value) ⇒ Object

A trace-hook processor for ‘trace var’



144
145
146
147
148
149
150
151
152
153
154
# File 'app/core.rb', line 144

def trace_var_processor(var_name, value)
    frame = RubyVM::Frame.get
    frame.trace_off = true
    frame.prev.trace_off = true
    # We need to skip this frame and the lamdba that in trace_var()
    # and a C call() in that lambda. See command/watchg.rb
    frame = RubyVM::Frame.get(3)

    @step_count = 0  # Make event processor stop
    event_processor(frame,  'trace-var', [var_name, value])
end