debugger-ide 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'