debugger-ide 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,153 @@
1
+ module Debugger
2
+ class ThreadListCommand < Command # :nodoc:
3
+ self.control = true
4
+ def regexp
5
+ /^\s*th(?:read)?\s+l(?:ist)?\s*$/
6
+ end
7
+
8
+ def execute
9
+ contexts = Debugger.contexts.sort_by{|c| c.thnum}
10
+ print_contexts(contexts)
11
+ end
12
+
13
+ class << self
14
+ def help_command
15
+ 'thread'
16
+ end
17
+
18
+ def help(cmd)
19
+ %{
20
+ th[read] l[ist]\t\t\tlist all threads
21
+ }
22
+ end
23
+ end
24
+ end
25
+
26
+ class ThreadSwitchCommand < Command # :nodoc:
27
+ self.control = true
28
+ self.need_context = true
29
+
30
+ def regexp
31
+ /^\s*th(?:read)?\s+(?:sw(?:itch)?\s+)?(\d+)\s*$/
32
+ end
33
+
34
+ def execute
35
+ c = get_context(@match[1].to_i)
36
+ case
37
+ when c == @state.context
38
+ print_msg "It's the current thread."
39
+ when c.ignored?
40
+ print_msg "Can't switch to the debugger thread."
41
+ else
42
+ print_context(c)
43
+ c.stop_next = 1
44
+ c.thread.run
45
+ @state.proceed
46
+ end
47
+ end
48
+
49
+ class << self
50
+ def help_command
51
+ 'thread'
52
+ end
53
+
54
+ def help(cmd)
55
+ %{
56
+ th[read] [sw[itch]] <nnn>\tswitch thread context to nnn
57
+ }
58
+ end
59
+ end
60
+ end
61
+
62
+ class ThreadStopCommand < Command # :nodoc:
63
+ self.control = true
64
+ self.need_context = true
65
+
66
+ def regexp
67
+ /^\s*th(?:read)?\s+stop\s+(\d+)\s*$/
68
+ end
69
+
70
+ def execute
71
+ c = get_context(@match[1].to_i)
72
+ case
73
+ when c == @state.context
74
+ print_msg "It's the current thread."
75
+ when c.ignored?
76
+ print_msg "Can't stop the debugger thread."
77
+ else
78
+ c.suspend
79
+ print_context(c)
80
+ end
81
+ end
82
+
83
+ class << self
84
+ def help_command
85
+ 'thread'
86
+ end
87
+
88
+ def help(cmd)
89
+ %{
90
+ th[read] stop <nnn>\t\tstop thread nnn
91
+ }
92
+ end
93
+ end
94
+ end
95
+
96
+ class ThreadCurrentCommand < Command # :nodoc:
97
+ self.need_context = true
98
+
99
+ def regexp
100
+ /^\s*th(?:read)?\s+c(?:ur(?:rent)?)?\s*$/
101
+ end
102
+
103
+ def execute
104
+ print_context(@state.context)
105
+ end
106
+
107
+ class << self
108
+ def help_command
109
+ 'thread'
110
+ end
111
+
112
+ def help(cmd)
113
+ %{
114
+ th[read] c[ur[rent]]\t\tshow current thread
115
+ }
116
+ end
117
+ end
118
+ end
119
+
120
+ class ThreadResumeCommand < Command # :nodoc:
121
+ self.control = true
122
+ self.need_context = true
123
+
124
+ def regexp
125
+ /^\s*th(?:read)?\s+resume\s+(\d+)\s*$/
126
+ end
127
+
128
+ def execute
129
+ c = get_context(@match[1].to_i)
130
+ case
131
+ when c == @state.context
132
+ print_msg "It's the current thread."
133
+ when c.ignored?
134
+ print_msg "Can't resume the debugger thread."
135
+ else
136
+ c.resume
137
+ print_context(c)
138
+ end
139
+ end
140
+
141
+ class << self
142
+ def help_command
143
+ 'thread'
144
+ end
145
+
146
+ def help(cmd)
147
+ %{
148
+ th[read] resume <nnn>\t\tresume thread nnn
149
+ }
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,142 @@
1
+ module Debugger
2
+ class VarConstantCommand < Command # :nodoc:
3
+ def regexp
4
+ /^\s*v(?:ar)?\s+c(?:onst(?:ant)?)?\s+/
5
+ end
6
+
7
+ def execute
8
+ obj = debug_eval(@match.post_match)
9
+ unless obj.kind_of? Module
10
+ print_msg "Should be Class/Module: %s", @match.post_match
11
+ else
12
+ print_variables(obj.constants, "constant") do |var|
13
+ obj.const_get(var)
14
+ end
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def help_command
20
+ 'var'
21
+ end
22
+
23
+ def help(cmd)
24
+ %{
25
+ v[ar] c[onst] <object>\t\tshow constants of object
26
+ }
27
+ end
28
+ end
29
+ end
30
+
31
+ class VarGlobalCommand < Command # :nodoc:
32
+ def regexp
33
+ /^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
34
+ end
35
+
36
+ def execute
37
+ globals = []
38
+ if RUBY_VERSION < "1.9"
39
+ globals = global_variables
40
+ else
41
+ Debugger::without_stderr { globals = global_variables - [:$KCODE, :$=] }
42
+ end
43
+ print_variables(globals, 'global') do |var|
44
+ debug_eval(var)
45
+ end
46
+ end
47
+
48
+ class << self
49
+ def help_command
50
+ 'var'
51
+ end
52
+
53
+ def help(cmd)
54
+ %{
55
+ v[ar] g[lobal]\t\t\tshow global variables
56
+ }
57
+ end
58
+ end
59
+ end
60
+
61
+ class VarInstanceCommand < Command # :nodoc:
62
+ def regexp
63
+ # id will be read as first match, name as post match
64
+ /^\s*v(?:ar)?\s+i(?:nstance)?\s+((?:[\\+-]0x)[\dabcdef]+)?/
65
+ end
66
+
67
+ def execute
68
+ if (@match[1])
69
+ obj = ObjectSpace._id2ref(@match[1].hex) rescue nil
70
+ unless obj
71
+ # TODO: ensure that empty variables frame will be printed
72
+ @printer.print_msg("Unknown object id : %s", @match[1])
73
+ end
74
+ else
75
+ obj = debug_eval(@match.post_match)
76
+ end
77
+ return unless obj
78
+ if (obj.is_a?(Array)) then
79
+ print_array(obj)
80
+ elsif (obj.is_a?(Hash)) then
81
+ print_hash(obj)
82
+ else
83
+ print_element("variables") do
84
+ # instance variables
85
+ kind = 'instance'
86
+ inst_vars = obj.instance_variables
87
+ instance_binding = obj.instance_eval{binding()}
88
+ # print self at top position
89
+ print_variable('self', debug_eval('self', instance_binding), kind) if inst_vars.include?('self')
90
+ inst_vars.sort.each do |var|
91
+ print_variable(var, debug_eval(var, instance_binding), kind) unless var == 'self'
92
+ end
93
+
94
+ # class variables
95
+ class_binding = obj.class.class_eval('binding()')
96
+ obj.class.class_variables.sort.each do |var|
97
+ print_variable(var, debug_eval(var, class_binding), 'class')
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ class << self
104
+ def help_command
105
+ 'var'
106
+ end
107
+
108
+ def help(cmd)
109
+ %{
110
+ v[ar] i[nstance] <object>\tshow instance variables of object, object can be given by its id or an expression
111
+ }
112
+ end
113
+ end
114
+ end
115
+
116
+ class VarLocalCommand < Command # :nodoc:
117
+ def regexp
118
+ /^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
119
+ end
120
+
121
+ def execute
122
+ locals = @state.context.frame_locals(@state.frame_pos)
123
+ _self = @state.context.frame_self(@state.frame_pos)
124
+ locals['self'] = _self unless _self.to_s == "main"
125
+ print_variables(locals.keys, 'local') do |var|
126
+ locals[var]
127
+ end
128
+ end
129
+
130
+ class << self
131
+ def help_command
132
+ 'var'
133
+ end
134
+
135
+ def help(cmd)
136
+ %{
137
+ v[ar] l[ocal]\t\t\tshow local variables
138
+ }
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,74 @@
1
+ if RUBY_VERSION < "1.9"
2
+ require 'ruby-debug/xml_printer'
3
+ else
4
+ require_relative 'xml_printer'
5
+ end
6
+ module Debugger
7
+
8
+ class EventProcessor
9
+
10
+ attr_accessor :line, :file, :context
11
+
12
+ def initialize(interface)
13
+ @printer = XmlPrinter.new(interface)
14
+ @line = nil
15
+ @file = nil
16
+ @last_breakpoint = nil
17
+ end
18
+
19
+ def at_breakpoint(context, breakpoint)
20
+ raise "@last_breakpoint supposed to be nil. is #{@last_breakpoint}" if @last_breakpoint
21
+ # at_breakpoint is immediately followed by #at_line event in
22
+ # ruby-debug-base. So postpone breakpoint printing until #at_line.
23
+ @last_breakpoint = breakpoint
24
+ end
25
+
26
+ def at_catchpoint(context, excpt)
27
+ @printer.print_catchpoint(excpt)
28
+ end
29
+
30
+ def at_tracing(context, file, line)
31
+ @printer.print_trace(context, file, line)
32
+ end
33
+
34
+ def at_line(context, file, line)
35
+ @printer.print_at_line(context, file, line) if context.nil? || context.stop_reason == :step
36
+ line_event(context, file, line)
37
+ end
38
+
39
+ def at_return(context, file, line)
40
+ @printer.print_at_line(context, file, line)
41
+ context.stop_frame = -1
42
+ line_event(context, file, line)
43
+ end
44
+
45
+ def line_event(context, file, line)
46
+ @line = line
47
+ @file = file
48
+ @context = context
49
+ if @last_breakpoint
50
+ # followed after #at_breakpoint in the same thread. Print breakpoint
51
+ # now when @line, @file and @context are correctly set to prevent race
52
+ # condition with `control thread'.
53
+ n = Debugger.breakpoints.index(@last_breakpoint) + 1
54
+ @printer.print_breakpoint n, @last_breakpoint
55
+ @last_breakpoint = nil
56
+ end
57
+ raise "DebuggerThread are not supposed to be traced (#{context.thread})" if context.thread.is_a?(Debugger::DebugThread)
58
+ @printer.print_debug("Stopping Thread %s", context.thread.to_s)
59
+ @printer.print_debug("Threads equal: %s", Thread.current == context.thread)
60
+ # will be resumed by commands like `step', `next', `continue', `finish'
61
+ # from `control thread'
62
+ Thread.stop
63
+ @printer.print_debug("Resumed Thread %s", context.thread.to_s)
64
+ @line = nil
65
+ @file = nil
66
+ @context = nil
67
+ end
68
+
69
+ def at_line?
70
+ @line
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,33 @@
1
+ module Debugger
2
+
3
+ module ParseFunctions
4
+ # Parse 'str' of command 'cmd' as an integer between
5
+ # min and max. If either min or max is nil, that
6
+ # value has no bound.
7
+ def get_int(str, cmd, min=nil, max=nil, default=1)
8
+ return default unless str
9
+ begin
10
+ int = Integer(str)
11
+ if min and int < min
12
+ print_error "%s argument '%s' needs to at least %s.\n" % [cmd, str, min]
13
+ return nil
14
+ elsif max and int > max
15
+ print_error "%s argument '%s' needs to at most %s.\n" % [cmd, str, max]
16
+ return nil
17
+ end
18
+ return int
19
+ rescue
20
+ print_error "%s argument '%s' needs to be a number.\n" % [cmd, str]
21
+ return nil
22
+ end
23
+ end
24
+
25
+ # Return true if code is syntactically correct for Ruby.
26
+ def syntax_valid?(code)
27
+ eval("BEGIN {return true}\n#{code}", nil, "", 0)
28
+ rescue Exception
29
+ false
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ class TCPSocket
2
+
3
+ # Workaround for JRuby issue http://jira.codehaus.org/browse/JRUBY-2063
4
+ def non_blocking_gets
5
+ loop do
6
+ result, _, _ = IO.select( [self], nil, nil, 0.2 )
7
+ next unless result
8
+ return result[0].gets
9
+ end
10
+ end
11
+
12
+ end
13
+
14
+ module Debugger
15
+
16
+ class RemoteInterface # :nodoc:
17
+
18
+ def initialize(socket)
19
+ @socket = socket
20
+ end
21
+
22
+ def read_command
23
+ result = @socket.non_blocking_gets
24
+ raise IOError unless result
25
+ result.chomp
26
+ end
27
+
28
+ def print(*args)
29
+ @socket.printf(*args)
30
+ end
31
+
32
+ def close
33
+ @socket.close
34
+ rescue Exception
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,2 @@
1
+ require 'ruby-debug/printers/plain_printer'
2
+ require 'ruby-debug/printers/xml_printer'