ruby-debug-ide 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
data/bin/rdebug-ide ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require "ostruct"
6
+ require 'ruby-debug'
7
+
8
+ $stdout.sync=true
9
+
10
+ options = OpenStruct.new(
11
+ 'host' => nil,
12
+ 'port' => 1234,
13
+ 'tracing' => false,
14
+ 'frame_bind' => false
15
+ )
16
+
17
+ opts = OptionParser.new do |opts|
18
+ opts.banner = <<EOB
19
+ Using ruby-debug-base #{Debugger::VERSION}
20
+ Usage: rdebug-javaide is supposed to be called from RDT or NetBeans. The command line interface to ruby-debug is rdebug.
21
+ EOB
22
+ opts.separator ""
23
+ opts.separator "Options:"
24
+ opts.on("-h", "--host HOST", "Host name used for remote debugging") {|options.host|}
25
+ opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|options.port|}
26
+ opts.on("-x", "--trace", "turn on line tracing") {options.tracing = true}
27
+ opts.on("-d", "--debug", "Debug self - prints information for debugging ruby-debug itself") do
28
+ Debugger.is_debug = true
29
+ end
30
+ opts.on("-I", "--include PATH", String, "Add PATH to $LOAD_PATH") do |path|
31
+ $LOAD_PATH.unshift(path)
32
+ end
33
+
34
+ opts.on("--keep-frame-binding", "Keep frame bindings") {options.frame_bind = true}
35
+ opts.separator ""
36
+ opts.separator "Common options:"
37
+ opts.on_tail("-v", "--version", "Show version") do
38
+ puts "Using ruby-debug-base #{Debugger::VERSION}"
39
+ exit
40
+ end
41
+ end
42
+
43
+ begin
44
+ Debugger::ARGV = ARGV.clone
45
+ rdebug_path = File.expand_path($0)
46
+ if RUBY_PLATFORM =~ /mswin/
47
+ rdebug_path += ".cmd" unless rdebug_path =~ /\.cmd$/i
48
+ end
49
+ Debugger::RDEBUG_SCRIPT = rdebug_path
50
+ opts.parse! ARGV
51
+ rescue StandardError => e
52
+ puts opts
53
+ puts
54
+ puts e.message
55
+ exit(1)
56
+ end
57
+
58
+ if ARGV.empty?
59
+ puts opts
60
+ puts
61
+ puts "Must specify a script to run"
62
+ exit(1)
63
+ end
64
+
65
+ # save script name
66
+ Debugger::PROG_SCRIPT = ARGV.shift
67
+
68
+ # install interruption handler
69
+ trap('INT') { Debugger.interrupt_last }
70
+
71
+ # set options
72
+ Debugger.keep_frame_binding = options.frame_bind
73
+
74
+ Debugger.main(options.host, options.port)
data/lib/ruby-debug.rb ADDED
@@ -0,0 +1,128 @@
1
+ require 'pp'
2
+ require 'stringio'
3
+ require "socket"
4
+ require 'thread'
5
+ require 'ruby_debug.so'
6
+ require 'ruby-debug/xml_printer'
7
+ require 'ruby-debug/processor'
8
+ require 'ruby-debug/event_processor'
9
+
10
+ module Debugger
11
+
12
+ class Context
13
+ def interrupt
14
+ self.stop_next = 1
15
+ end
16
+
17
+ private
18
+
19
+ def processor
20
+ Debugger.processor
21
+ end
22
+
23
+ def at_breakpoint(breakpoint)
24
+ processor.at_breakpoint(self, breakpoint)
25
+ end
26
+
27
+ def at_catchpoint(excpt)
28
+ processor.at_catchpoint(self, excpt)
29
+ end
30
+
31
+ def at_tracing(file, line)
32
+ processor.at_tracing(self, file, line)
33
+ end
34
+
35
+ def at_line(file, line)
36
+ processor.at_line(self, file, line)
37
+ end
38
+ end
39
+
40
+ class << self
41
+ attr_accessor :processor, :is_debug
42
+ attr_reader :control_thread
43
+
44
+ #
45
+ # Interrupts the current thread
46
+ #
47
+ def interrupt
48
+ current_context.interrupt
49
+ end
50
+
51
+ #
52
+ # Interrupts the last debugged thread
53
+ #
54
+ def interrupt_last
55
+ skip do
56
+ if context = last_context
57
+ return nil unless context.thread.alive?
58
+ context.interrupt
59
+ end
60
+ context
61
+ end
62
+ end
63
+
64
+ def main(host, port)
65
+ return if started?
66
+
67
+ start
68
+
69
+ start_control(host, port)
70
+
71
+ @mutex = Mutex.new
72
+ @proceed = ConditionVariable.new
73
+
74
+ # wait for start command
75
+ @mutex.synchronize do
76
+ @proceed.wait(@mutex)
77
+ end
78
+
79
+ debug_load Debugger::PROG_SCRIPT
80
+ end
81
+
82
+ def run_prog_script
83
+ @mutex.synchronize do
84
+ @proceed.signal
85
+ end
86
+ end
87
+
88
+ def start_control(host, port)
89
+ raise "Debugger is not started" unless started?
90
+ return if @control_thread
91
+ @control_thread = DebugThread.new do
92
+ server = TCPServer.new(host, port)
93
+ while (session = server.accept)
94
+ begin
95
+ interface = RemoteInterface.new(session)
96
+ @processor = EventProcessor.new(interface)
97
+ processor = ControlCommandProcessor.new(interface)
98
+ processor.process_commands
99
+ rescue StandardError, ScriptError => ex
100
+ puts ex
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ class Exception # :nodoc:
109
+ attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_context
110
+ end
111
+
112
+ module Kernel
113
+ #
114
+ # Stops the current thread after a number of _steps_ made.
115
+ #
116
+ def debugger(steps = 1)
117
+ Debugger.current_context.stop_next = steps
118
+ end
119
+
120
+ #
121
+ # Returns a binding of n-th call frame
122
+ #
123
+ def binding_n(n = 0)
124
+ Debugger.current_context.frame_binding[n+1]
125
+ end
126
+ end
127
+
128
+ end
@@ -0,0 +1,114 @@
1
+ module Debugger
2
+ class Command # :nodoc:
3
+ class << self
4
+ def commands
5
+ @commands ||= []
6
+ end
7
+
8
+ DEF_OPTIONS = {
9
+ :event => true,
10
+ :control => false,
11
+ :unknown => false,
12
+ :need_context => false,
13
+ }
14
+
15
+ def inherited(klass)
16
+ DEF_OPTIONS.each do |o, v|
17
+ klass.options[o] = v if klass.options[o].nil?
18
+ end
19
+ commands << klass
20
+ end
21
+
22
+ def load_commands
23
+ dir = File.dirname(__FILE__)
24
+ Dir[File.join(dir, 'commands', '*')].each do |file|
25
+ require file if file =~ /\.rb$/
26
+ end
27
+ end
28
+
29
+ def method_missing(meth, *args, &block)
30
+ if meth.to_s =~ /^(.+?)=$/
31
+ @options[$1.intern] = args.first
32
+ else
33
+ if @options.has_key?(meth)
34
+ @options[meth]
35
+ else
36
+ super
37
+ end
38
+ end
39
+ end
40
+
41
+ def options
42
+ @options ||= {}
43
+ end
44
+ end
45
+
46
+ def initialize(state, printer)
47
+ @state, @printer = state, printer
48
+ end
49
+
50
+ def match(input)
51
+ @match = regexp.match(input)
52
+ end
53
+
54
+ protected
55
+
56
+ def method_missing(meth, *args, &block)
57
+ if @printer.respond_to? meth
58
+ @printer.send meth, *args, &block
59
+ else
60
+ super
61
+ end
62
+ end
63
+
64
+ def print(*args)
65
+ @state.print(*args)
66
+ end
67
+
68
+ def confirm(msg)
69
+ @state.confirm(msg) == 'y'
70
+ end
71
+
72
+ def debug_eval(str, b = get_binding)
73
+ begin
74
+ val = eval(str, b)
75
+ rescue StandardError, ScriptError => e
76
+ @printer.print_exception(e, @state.binding)
77
+ throw :debug_error
78
+ end
79
+ end
80
+
81
+ def debug_silent_eval(str)
82
+ begin
83
+ eval(str, get_binding)
84
+ rescue StandardError, ScriptError
85
+ nil
86
+ end
87
+ end
88
+
89
+ def hbinding(hash)
90
+ code = hash.keys.map{|k| "#{k} = hash['#{k}']"}.join(';') + ';binding'
91
+ if obj = @state.context.frame_self(@state.frame_pos)
92
+ obj.instance_eval code
93
+ else
94
+ eval code
95
+ end
96
+ end
97
+ private :hbinding
98
+
99
+ def get_binding
100
+ binding = @state.context.frame_binding(@state.frame_pos)
101
+ binding || hbinding(@state.context.frame_locals(@state.frame_pos))
102
+ end
103
+
104
+ def line_at(file, line)
105
+ Debugger.line_at(file, line)
106
+ end
107
+
108
+ def get_context(thnum)
109
+ Debugger.contexts.find{|c| c.thnum == thnum}
110
+ end
111
+ end
112
+
113
+ Command.load_commands
114
+ end
@@ -0,0 +1,126 @@
1
+ module Debugger
2
+ class AddBreakpoint < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ / ^\s*
7
+ b(?:reak)?
8
+ \s+
9
+ (?:
10
+ (\d+) |
11
+ (.+?)[:.#]([^.:\s]+)
12
+ )
13
+ (?:\s+
14
+ if\s+(.+)
15
+ )?
16
+ $
17
+ /x
18
+ end
19
+
20
+ def execute
21
+ if @match[1]
22
+ pos, _, _, expr = @match.captures
23
+ else
24
+ _, file, pos, expr = @match.captures
25
+ end
26
+
27
+ if file.nil?
28
+ file = File.basename(@state.file)
29
+ else
30
+ if pos !~ /^\d+$/
31
+ klass = debug_silent_eval(file)
32
+ if klass && !klass.kind_of?(Module)
33
+ print_error "Unknown class #{file}"
34
+ throw :debug_error
35
+ end
36
+ file = klass.name if klass
37
+ else
38
+ file = File.expand_path(file) if file.index(File::SEPARATOR) || \
39
+ File::ALT_SEPARATOR && file.index(File::ALT_SEPARATOR)
40
+ end
41
+ end
42
+
43
+ if pos =~ /^\d+$/
44
+ pos = pos.to_i
45
+ else
46
+ pos = pos.intern.id2name
47
+ end
48
+
49
+ b = Debugger.add_breakpoint file, pos, expr
50
+ print_breakpoint_added b
51
+ end
52
+
53
+ class << self
54
+ def help_command
55
+ 'break'
56
+ end
57
+
58
+ def help(cmd)
59
+ %{
60
+ b[reak] [file|class(:|.|#)]<line|method> [if expr] -
61
+ \tset breakpoint to some position, (optionally) if expr == true
62
+ }
63
+ end
64
+ end
65
+ end
66
+
67
+ class BreakpointsCommand < Command # :nodoc:
68
+ self.control = true
69
+
70
+ def regexp
71
+ /^\s*b(?:reak)?$/
72
+ end
73
+
74
+ def execute
75
+ print_breakpoints Debugger.breakpoints
76
+ end
77
+
78
+ class << self
79
+ def help_command
80
+ 'break'
81
+ end
82
+
83
+ def help(cmd)
84
+ %{
85
+ b[reak]\tlist breakpoints
86
+ }
87
+ end
88
+ end
89
+ end
90
+
91
+ class DeleteBreakpointCommand < Command # :nodoc:
92
+ self.control = true
93
+
94
+ def regexp
95
+ /^\s*del(?:ete)?(?:\s+(\d+))?$/
96
+ end
97
+
98
+ def execute
99
+ pos = @match[1]
100
+ unless pos
101
+ if confirm("Clear all breakpoints? (y/n) ")
102
+ Debugger.breakpoints.clear
103
+ end
104
+ else
105
+ pos = pos.to_i
106
+ if b = Debugger.remove_breakpoint(pos)
107
+ print_breakpoint_deleted b
108
+ else
109
+ print_error "Breakpoint %d is not defined", pos
110
+ end
111
+ end
112
+ end
113
+
114
+ class << self
115
+ def help_command
116
+ 'delete'
117
+ end
118
+
119
+ def help(cmd)
120
+ %{
121
+ del[ete][ nnn]\tdelete some or all breakpoints
122
+ }
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,40 @@
1
+ module Debugger
2
+ class CatchCommand < Command # :nodoc:
3
+ self.control = true
4
+
5
+ def regexp
6
+ /^\s*cat(?:ch)?(?:\s+(.+))?$/
7
+ end
8
+
9
+ def execute
10
+ if excn = @match[1]
11
+ if excn == 'off'
12
+ Debugger.catchpoint = nil
13
+ print_msg "Clear catchpoint."
14
+ else
15
+ Debugger.catchpoint = excn
16
+ print_msg "Set catchpoint %s.", excn
17
+ end
18
+ else
19
+ if Debugger.catchpoint
20
+ print_msg "Catchpoint %s.", Debugger.catchpoint
21
+ else
22
+ print_msg "No catchpoint."
23
+ end
24
+ end
25
+ end
26
+
27
+ class << self
28
+ def help_command
29
+ 'catch'
30
+ end
31
+
32
+ def help(cmd)
33
+ %{
34
+ cat[ch]\t\t\tshow catchpoint
35
+ cat[ch] <an Exception>\tset catchpoint to an exception
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end