ruby-debug-ide 0.1.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.
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