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.
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