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.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+
4
+ # gem "rails"
@@ -0,0 +1,24 @@
1
+ The file lib/classic-debug.rb is based on the debug.rb file from Ruby
2
+ project.
3
+
4
+ Copyright (c) 2007-2008, debug-commons team
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+
@@ -0,0 +1,108 @@
1
+ require 'rubygems'
2
+
3
+ require 'rake/gempackagetask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/testtask'
6
+ require 'date'
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => [:test]
10
+
11
+ # ------- Default Package ----------
12
+ RUBY_DEBUG_IDE_VERSION = "0.4.13"
13
+
14
+ FILES = FileList[
15
+ # 'CHANGES',
16
+ # 'ChangeLog',
17
+ # 'ChangeLog.archive',
18
+ 'MIT-LICENSE',
19
+ 'Rakefile',
20
+ 'bin/*',
21
+ 'lib/**/*'
22
+ # 'test/**/*'
23
+ ]
24
+
25
+ ide_spec = Gem::Specification.new do |spec|
26
+ spec.name = "ruby-debug-ide19"
27
+
28
+ spec.homepage = "http://rubyforge.org/projects/ruby-debug19"
29
+ spec.summary = "IDE interface for ruby-debug."
30
+ spec.description = <<-EOF
31
+ An interface which glues ruby-debug to IDEs like Eclipse (RDT) and NetBeans.
32
+ EOF
33
+
34
+ spec.version = RUBY_DEBUG_IDE_VERSION
35
+
36
+ spec.author = "Markus Barchfeld, Martin Krauskopf, Mark Moseley"
37
+ spec.email = "mark@fast-software.com"
38
+ spec.platform = Gem::Platform::RUBY
39
+ spec.require_path = "lib"
40
+ spec.bindir = "bin"
41
+ spec.executables = ["rdebug-ide"]
42
+ spec.files = FILES.to_a
43
+ spec.add_dependency("debugger", "~> 1.2.1")
44
+
45
+ spec.required_ruby_version = '>= 1.8.2'
46
+ spec.date = DateTime.now
47
+ spec.rubyforge_project = 'debug-commons'
48
+
49
+ # rdoc
50
+ spec.has_rdoc = false
51
+ end
52
+
53
+ # Rake task to build the default package
54
+ Rake::GemPackageTask.new(ide_spec) do |pkg|
55
+ pkg.need_tar = true
56
+ end
57
+
58
+ # Unit tests
59
+ Rake::TestTask.new do |t|
60
+ t.libs << "test"
61
+ t.libs << "test-base"
62
+ t.pattern = 'test/*_test.rb'
63
+ t.verbose = true
64
+ t.warning = false
65
+ end
66
+
67
+
68
+ desc "Create a GNU-style ChangeLog via svn2cl"
69
+ task :ChangeLog do
70
+ system("svn2cl --authors=svn2cl_usermap svn://rubyforge.org/var/svn/debug-commons/ruby-debug-ide/trunk -o ChangeLog")
71
+ end
72
+
73
+ #desc "Publish ruby-debug to RubyForge."
74
+ #task :publish do
75
+ # require 'rake/contrib/sshpublisher'
76
+ #
77
+ # # Get ruby-debug path
78
+ # ruby_debug_path = File.expand_path(File.dirname(__FILE__))
79
+ #
80
+ # publisher = Rake::SshDirPublisher.new("kent@rubyforge.org",
81
+ # "/var/www/gforge-projects/ruby-debug", ruby_debug_path)
82
+ #end
83
+ #
84
+ #desc "Clear temp files"
85
+ #task :clean do
86
+ # cd "ext" do
87
+ # if File.exists?("Makefile")
88
+ # sh "make clean"
89
+ # rm "Makefile"
90
+ # end
91
+ # end
92
+ #end
93
+ #
94
+ ## --------- RDoc Documentation ------
95
+ #desc "Generate rdoc documentation"
96
+ #Rake::RDocTask.new("rdoc") do |rdoc|
97
+ # rdoc.rdoc_dir = 'doc'
98
+ # rdoc.title = "ruby-debug"
99
+ # # Show source inline with line numbers
100
+ # rdoc.options << "--inline-source" << "--line-numbers"
101
+ # # Make the readme file the start page for the generated html
102
+ # rdoc.options << '--main' << 'README'
103
+ # rdoc.rdoc_files.include('bin/**/*',
104
+ # 'lib/**/*.rb',
105
+ # 'ext/**/ruby_debug.c',
106
+ # 'README',
107
+ # 'LICENSE')
108
+ #end
@@ -0,0 +1,184 @@
1
+ require 'pp'
2
+ require 'stringio'
3
+ require "socket"
4
+ require 'thread'
5
+ require 'debugger'
6
+ if RUBY_VERSION < "1.9"
7
+ require 'ruby-debug/xml_printer'
8
+ require 'ruby-debug/processor'
9
+ require 'ruby-debug/event_processor'
10
+ else
11
+ require_relative 'ruby-debug/xml_printer'
12
+ require_relative 'ruby-debug/processor'
13
+ require_relative 'ruby-debug/event_processor'
14
+ end
15
+
16
+ module Debugger
17
+
18
+ class << self
19
+ # Prints to the stderr using printf(*args) if debug logging flag (-d) is on.
20
+ def print_debug(*args)
21
+ if Debugger.cli_debug
22
+ $stderr.printf(*args)
23
+ $stderr.printf("\n")
24
+ $stderr.flush
25
+ end
26
+ end
27
+
28
+ def without_stderr
29
+ begin
30
+ if RUBY_PLATFORM =~ /(win32|mingw32)/
31
+ $stderr = File.open('NUL', 'w')
32
+ else
33
+ $stderr = File.open('/dev/null', 'w')
34
+ end
35
+ yield
36
+ ensure
37
+ $stderr = STDERR
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ class Context
44
+ def interrupt
45
+ self.stop_next = 1
46
+ end
47
+
48
+ private
49
+
50
+ def event_processor
51
+ Debugger.event_processor
52
+ end
53
+
54
+ def at_breakpoint(breakpoint)
55
+ event_processor.at_breakpoint(self, breakpoint)
56
+ end
57
+
58
+ def at_catchpoint(excpt)
59
+ event_processor.at_catchpoint(self, excpt)
60
+ end
61
+
62
+ def at_tracing(file, line)
63
+ if event_processor
64
+ event_processor.at_tracing(self, file, line)
65
+ else
66
+ Debugger::print_debug "trace: location=\"%s:%s\", threadId=%d", file, line, self.thnum
67
+ end
68
+ end
69
+
70
+ def at_line(file, line)
71
+ event_processor.at_line(self, file, line)
72
+ end
73
+
74
+ def at_return(file, line)
75
+ event_processor.at_return(self, file, line)
76
+ end
77
+ end
78
+
79
+ class << self
80
+
81
+ attr_accessor :event_processor, :cli_debug, :xml_debug
82
+ attr_reader :control_thread
83
+
84
+ #
85
+ # Interrupts the current thread
86
+ #
87
+ def interrupt
88
+ current_context.interrupt
89
+ end
90
+
91
+ #
92
+ # Interrupts the last debugged thread
93
+ #
94
+ def interrupt_last
95
+ skip do
96
+ if context = last_context
97
+ return nil unless context.thread.alive?
98
+ context.interrupt
99
+ end
100
+ context
101
+ end
102
+ end
103
+
104
+ def start_server(host = nil, port = 1234)
105
+ start
106
+ start_control(host, port)
107
+ end
108
+
109
+ def debug_program(options)
110
+ start_server(options.host, options.port)
111
+
112
+ raise "Control thread did not start (#{@control_thread}}" unless @control_thread && @control_thread.alive?
113
+
114
+ @mutex = Mutex.new
115
+ @proceed = ConditionVariable.new
116
+
117
+ # wait for 'start' command
118
+ @mutex.synchronize do
119
+ @proceed.wait(@mutex)
120
+ end
121
+
122
+ bt = debug_load(Debugger::PROG_SCRIPT, options.stop, options.load_mode)
123
+ if bt
124
+ $stderr.print bt.backtrace.map{|l| "\t#{l}"}.join("\n"), "\n"
125
+ $stderr.print "Uncaught exception: #{bt}\n"
126
+ end
127
+ end
128
+
129
+ def run_prog_script
130
+ return unless @mutex
131
+ @mutex.synchronize do
132
+ @proceed.signal
133
+ end
134
+ end
135
+
136
+ def start_control(host, port)
137
+ return if @control_thread
138
+ @control_thread = DebugThread.new do
139
+ begin
140
+ $stderr.printf "Fast Debugger (ruby-debug-ide 0.4.9) listens on #{host}:#{port}\n"
141
+ # 127.0.0.1 seemingly works with all systems and with IPv6 as well.
142
+ # "localhost" and nil on have problems on some systems.
143
+ host ||= '127.0.0.1'
144
+ server = TCPServer.new(host, port)
145
+ while (session = server.accept)
146
+ begin
147
+ interface = RemoteInterface.new(session)
148
+ @event_processor = EventProcessor.new(interface)
149
+ ControlCommandProcessor.new(interface).process_commands
150
+ rescue StandardError, ScriptError => ex
151
+ $stderr.printf "Exception in DebugThread loop: #{ex}\n"
152
+ exit 1
153
+ end
154
+ end
155
+ rescue
156
+ $stderr.printf "Exception in DebugThread: #$!\n"
157
+ exit 2
158
+ end
159
+ end
160
+ end
161
+
162
+ end
163
+
164
+ class Exception # :nodoc:
165
+ attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_context
166
+ end
167
+
168
+ module Kernel
169
+ #
170
+ # Stops the current thread after a number of _steps_ made.
171
+ #
172
+ def debugger(steps = 1)
173
+ Debugger.current_context.stop_next = steps
174
+ end
175
+
176
+ #
177
+ # Returns a binding of n-th call frame
178
+ #
179
+ def binding_n(n = 0)
180
+ Debugger.current_context.frame_binding[n+1]
181
+ end
182
+ end
183
+
184
+ end
@@ -0,0 +1,173 @@
1
+ if RUBY_VERSION < "1.9"
2
+ require 'ruby-debug/helper'
3
+ else
4
+ require_relative 'helper'
5
+ end
6
+
7
+
8
+ module Debugger
9
+
10
+ class Command # :nodoc:
11
+ SubcmdStruct=Struct.new(:name, :min, :short_help, :long_help) unless
12
+ defined?(SubcmdStruct)
13
+
14
+ # Find param in subcmds. param id downcased and can be abbreviated
15
+ # to the minimum length listed in the subcommands
16
+ def find(subcmds, param)
17
+ param.downcase!
18
+ for try_subcmd in subcmds do
19
+ if (param.size >= try_subcmd.min) and
20
+ (try_subcmd.name[0..param.size-1] == param)
21
+ return try_subcmd
22
+ end
23
+ end
24
+ return nil
25
+ end
26
+
27
+ class << self
28
+ def commands
29
+ @commands ||= []
30
+ end
31
+
32
+ DEF_OPTIONS = {
33
+ :event => true,
34
+ :control => false,
35
+ :unknown => false,
36
+ :need_context => false,
37
+ }
38
+
39
+ def inherited(klass)
40
+ DEF_OPTIONS.each do |o, v|
41
+ klass.options[o] = v if klass.options[o].nil?
42
+ end
43
+ commands << klass
44
+ end
45
+
46
+ def load_commands
47
+ dir = File.dirname(__FILE__)
48
+ Dir[File.join(dir, 'commands', '*')].each do |file|
49
+ require file if file =~ /\.rb$/
50
+ end
51
+ Debugger.constants.grep(/Functions$/).map { |name| Debugger.const_get(name) }.each do |mod|
52
+ include mod
53
+ end
54
+ end
55
+
56
+ def method_missing(meth, *args, &block)
57
+ if meth.to_s =~ /^(.+?)=$/
58
+ @options[$1.intern] = args.first
59
+ else
60
+ if @options.has_key?(meth)
61
+ @options[meth]
62
+ else
63
+ super
64
+ end
65
+ end
66
+ end
67
+
68
+ def options
69
+ @options ||= {}
70
+ end
71
+ end
72
+
73
+ def initialize(state, printer)
74
+ @state, @printer = state, printer
75
+ end
76
+
77
+ def match(input)
78
+ @match = regexp.match(input)
79
+ end
80
+
81
+ protected
82
+
83
+ def method_missing(meth, *args, &block)
84
+ if @printer.respond_to? meth
85
+ @printer.send meth, *args, &block
86
+ else
87
+ super
88
+ end
89
+ end
90
+
91
+ # FIXME: use delegate?
92
+ def errmsg(*args)
93
+ @printer.print_error(*args)
94
+ end
95
+
96
+ def print(*args)
97
+ @state.print(*args)
98
+ end
99
+
100
+ # see Timeout::timeout, the difference is that we must use a DebugThread
101
+ # because every other thread would be halted when the event hook is reached
102
+ # in ruby-debug.c
103
+ def timeout(sec)
104
+ return yield if sec == nil or sec.zero?
105
+ if Thread.respond_to?(:critical) and Thread.critical
106
+ raise ThreadError, "timeout within critical session"
107
+ end
108
+ begin
109
+ x = Thread.current
110
+ y = DebugThread.start {
111
+ sleep sec
112
+ x.raise StandardError, "Timeout: evaluation took longer than #{sec} seconds." if x.alive?
113
+ }
114
+ yield sec
115
+ ensure
116
+ y.kill if y and y.alive?
117
+ end
118
+ end
119
+
120
+ def debug_eval(str, b = get_binding)
121
+ begin
122
+ str = str.to_s
123
+ max_time = 10
124
+ to_inspect = str.gsub(/\\n/, "\n")
125
+ @printer.print_debug("Evaluating with timeout after %i sec", max_time)
126
+ timeout(max_time) do
127
+ if RUBY_VERSION < "1.9"
128
+ eval(to_inspect, b)
129
+ else
130
+ Debugger::without_stderr { eval(to_inspect, b) }
131
+ end
132
+ end
133
+ rescue StandardError, ScriptError => e
134
+ @printer.print_exception(e, @state.binding)
135
+ throw :debug_error
136
+ end
137
+ end
138
+
139
+ def debug_silent_eval(str)
140
+ begin
141
+ str = str.to_s
142
+ eval(str, get_binding)
143
+ rescue StandardError, ScriptError
144
+ nil
145
+ end
146
+ end
147
+
148
+ def hbinding(hash)
149
+ code = hash.keys.map{|k| "#{k} = hash['#{k}']"}.join(';') + ';binding'
150
+ if obj = @state.context.frame_self(@state.frame_pos)
151
+ obj.instance_eval code
152
+ else
153
+ eval code
154
+ end
155
+ end
156
+ private :hbinding
157
+
158
+ def get_binding
159
+ binding = @state.context.frame_binding(@state.frame_pos)
160
+ binding || hbinding(@state.context.frame_locals(@state.frame_pos))
161
+ end
162
+
163
+ def line_at(file, line)
164
+ Debugger.line_at(file, line)
165
+ end
166
+
167
+ def get_context(thnum)
168
+ Debugger.contexts.find{|c| c.thnum == thnum}
169
+ end
170
+ end
171
+
172
+ Command.load_commands
173
+ end