ruby-debug-base19 0.11.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,302 @@
1
+ require 'ruby_debug.so'
2
+ require 'rubygems'
3
+ require 'linecache19'
4
+
5
+ module Debugger
6
+
7
+ # Default options to Debugger.start
8
+ DEFAULT_START_SETTINGS = {
9
+ :init => true, # Set $0 and save ARGV?
10
+ :post_mortem => false, # post-mortem debugging on uncaught exception?
11
+ :tracing => nil # Debugger.tracing value. true/false resets,
12
+ # nil keeps the prior value
13
+ } unless defined?(DEFAULT_START_SETTINGS)
14
+
15
+ class Context
16
+ def interrupt
17
+ self.stop_next = 1
18
+ end
19
+
20
+ alias __c_frame_binding frame_binding
21
+ def frame_binding(frame)
22
+ __c_frame_binding(frame) || hbinding(frame)
23
+ end
24
+
25
+ private
26
+
27
+ def hbinding(frame)
28
+ hash = frame_locals(frame)
29
+ code = hash.keys.map{|k| "#{k} = hash['#{k}']" unless k=='self' }.compact.join(';') + ';binding'
30
+ if obj = frame_self(frame)
31
+ obj.instance_eval code
32
+ else
33
+ eval code, TOPLEVEL_BINDING
34
+ end
35
+ end
36
+
37
+ def handler
38
+ Debugger.handler or raise 'No interface loaded'
39
+ end
40
+
41
+ def at_breakpoint(breakpoint)
42
+ handler.at_breakpoint(self, breakpoint)
43
+ end
44
+
45
+ def at_catchpoint(excpt)
46
+ handler.at_catchpoint(self, excpt)
47
+ end
48
+
49
+ def at_tracing(file, line)
50
+ handler.at_tracing(self, file, line)
51
+ end
52
+
53
+ def at_line(file, line)
54
+ handler.at_line(self, file, line)
55
+ end
56
+
57
+ def at_return(file, line)
58
+ handler.at_return(self, file, line)
59
+ end
60
+ end
61
+
62
+ @reload_source_on_change = false
63
+
64
+ class << self
65
+ # interface modules provide +handler+ object
66
+ attr_accessor :handler
67
+
68
+ # if <tt>true</tt>, checks the modification time of source files and reloads if it was modified
69
+ attr_accessor :reload_source_on_change
70
+
71
+ attr_accessor :last_exception
72
+ Debugger.last_exception = nil
73
+
74
+ #
75
+ # Interrupts the current thread
76
+ #
77
+ def interrupt
78
+ current_context.interrupt
79
+ end
80
+
81
+ #
82
+ # Interrupts the last debugged thread
83
+ #
84
+ def interrupt_last
85
+ if context = last_context
86
+ return nil unless context.thread.alive?
87
+ context.interrupt
88
+ end
89
+ context
90
+ end
91
+
92
+ def source_reload
93
+ LineCache::clear_file_cache(true)
94
+ end
95
+
96
+ # Get line +line_number+ from file named +filename+. Return "\n"
97
+ # there was a problem. Leaking blanks are stripped off.
98
+ def line_at(filename, line_number) # :nodoc:
99
+ @reload_on_change=nil unless defined?(@reload_on_change)
100
+ line = LineCache::getline(filename, line_number, @reload_on_change)
101
+ return "\n" unless line
102
+ return "#{line.gsub(/^\s+/, '').chomp}\n"
103
+ end
104
+
105
+ #
106
+ # Activates the post-mortem mode. There are two ways of using it:
107
+ #
108
+ # == Global post-mortem mode
109
+ # By calling Debugger.post_mortem method without a block, you install
110
+ # at_exit hook that intercepts any unhandled by your script exceptions
111
+ # and enables post-mortem mode.
112
+ #
113
+ # == Local post-mortem mode
114
+ #
115
+ # If you know that a particular block of code raises an exception you can
116
+ # enable post-mortem mode by wrapping this block with Debugger.post_mortem, e.g.
117
+ #
118
+ # def offender
119
+ # raise 'error'
120
+ # end
121
+ # Debugger.post_mortem do
122
+ # ...
123
+ # offender
124
+ # ...
125
+ # end
126
+ def post_mortem
127
+ if block_given?
128
+ old_post_mortem = self.post_mortem?
129
+ begin
130
+ self.post_mortem = true
131
+ yield
132
+ rescue Exception => exp
133
+ handle_post_mortem(exp)
134
+ raise
135
+ ensure
136
+ self.post_mortem = old_post_mortem
137
+ end
138
+ else
139
+ return if post_mortem?
140
+ self.post_mortem = true
141
+ debug_at_exit do
142
+ handle_post_mortem($!) if $! && post_mortem?
143
+ end
144
+ end
145
+ end
146
+
147
+ def handle_post_mortem(exp)
148
+ return if !exp || !exp.__debug_context ||
149
+ exp.__debug_context.stack_size == 0
150
+ Debugger.suspend
151
+ orig_tracing = Debugger.tracing, Debugger.current_context.tracing
152
+ Debugger.tracing = Debugger.current_context.tracing = false
153
+ Debugger.last_exception = exp
154
+ handler.at_line(exp.__debug_context, exp.__debug_file, exp.__debug_line)
155
+ ensure
156
+ Debugger.tracing, Debugger.current_context.tracing = orig_tracing
157
+ Debugger.resume
158
+ end
159
+ # private :handle_post_mortem
160
+ end
161
+
162
+ class DebugThread # :nodoc:
163
+ end
164
+
165
+ class ThreadsTable # :nodoc:
166
+ end
167
+
168
+ # Debugger.start(options) -> bool
169
+ # Debugger.start(options) { ... } -> obj
170
+ #
171
+ # If it's called without a block it returns +true+, unless debugger
172
+ # was already started. If a block is given, it starts debugger and
173
+ # yields to block. When the block is finished executing it stops
174
+ # the debugger with Debugger.stop method.
175
+ #
176
+ # If a block is given, it starts debugger and yields to block. When
177
+ # the block is finished executing it stops the debugger with
178
+ # Debugger.stop method. Inside the block you will probably want to
179
+ # have a call to Debugger.debugger. For example:
180
+ #
181
+ # Debugger.start{debugger; foo} # Stop inside of foo
182
+ #
183
+ # Also, ruby-debug only allows
184
+ # one invocation of debugger at a time; nested Debugger.start's
185
+ # have no effect and you can't use this inside the debugger itself.
186
+ #
187
+ # <i>Note that if you want to stop debugger, you must call
188
+ # Debugger.stop as many time as you called Debugger.start
189
+ # method.</i>
190
+ #
191
+ # +options+ is a hash used to set various debugging options.
192
+ # Set :init true if you want to save ARGV and some variables which
193
+ # make a debugger restart possible. Only the first time :init is set true
194
+ # will values get set. Since ARGV is saved, you should make sure
195
+ # it hasn't been changed before the (first) call.
196
+ # Set :post_mortem true if you want to enter post-mortem debugging
197
+ # on an uncaught exception. Once post-mortem debugging is set, it can't
198
+ # be unset.
199
+ def start(options={}, &block)
200
+ options = Debugger::DEFAULT_START_SETTINGS.merge(options)
201
+ if options[:init]
202
+ Debugger.const_set('ARGV', ARGV.clone) unless
203
+ defined? Debugger::ARGV
204
+ Debugger.const_set('PROG_SCRIPT', $0) unless
205
+ defined? Debugger::PROG_SCRIPT
206
+ Debugger.const_set('INITIAL_DIR', Dir.pwd) unless
207
+ defined? Debugger::INITIAL_DIR
208
+ end
209
+ Debugger.tracing = options[:tracing] unless options[:tracing].nil?
210
+ retval = Debugger.started? ? block && block.call(self) : Debugger.start_(&block)
211
+ if options[:post_mortem]
212
+ post_mortem
213
+ end
214
+ return retval
215
+ end
216
+ module_function :start
217
+ end
218
+
219
+ module Kernel
220
+
221
+ # Enters the debugger in the current thread after _steps_ line events occur.
222
+ # Before entering the debugger startup script is read.
223
+ #
224
+ # Setting _steps_ to 0 will cause a break in the debugger subroutine
225
+ # and not wait for a line event to occur. You will have to go "up 1"
226
+ # in order to be back in your debugged program rather than the
227
+ # debugger. Settings _steps_ to 0 could be useful you want to stop
228
+ # right after the last statement in some scope, because the next
229
+ # step will take you out of some scope.
230
+
231
+ # If a block is given (and the debugger hasn't been started, we run the
232
+ # block under the debugger. Alas, when a block is given, we can't support
233
+ # running the startup script or support the steps option. FIXME.
234
+ def debugger(steps = 1, &block)
235
+ if block
236
+ Debugger.start({}, &block)
237
+ else
238
+ Debugger.start unless Debugger.started?
239
+ Debugger.run_init_script(StringIO.new)
240
+ if 0 == steps
241
+ Debugger.current_context.stop_frame = 0
242
+ else
243
+ Debugger.current_context.stop_next = steps
244
+ end
245
+ end
246
+ end
247
+ alias breakpoint debugger unless respond_to?(:breakpoint)
248
+
249
+ #
250
+ # Returns a binding of n-th call frame
251
+ #
252
+ def binding_n(n = 0)
253
+ Debugger.skip do
254
+ if RUBY_VERSION < "1.9"
255
+ Debugger.current_context.frame_binding(n+2)
256
+ else
257
+ Debugger.current_context.frame_binding(n+1)
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ class Exception # :nodoc:
264
+ attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_context
265
+ end
266
+
267
+ class Module
268
+ #
269
+ # Wraps the +meth+ method with Debugger.start {...} block.
270
+ #
271
+ def debug_method(meth)
272
+ old_meth = "__debugee_#{meth}"
273
+ old_meth = "#{$1}_set" if old_meth =~ /^(.+)=$/
274
+ alias_method old_meth.to_sym, meth
275
+ class_eval <<-EOD
276
+ def #{meth}(*args, &block)
277
+ Debugger.start do
278
+ debugger 2
279
+ #{old_meth}(*args, &block)
280
+ end
281
+ end
282
+ EOD
283
+ end
284
+
285
+ #
286
+ # Wraps the +meth+ method with Debugger.post_mortem {...} block.
287
+ #
288
+ def post_mortem_method(meth)
289
+ old_meth = "__postmortem_#{meth}"
290
+ old_meth = "#{$1}_set" if old_meth =~ /^(.+)=$/
291
+ alias_method old_meth.to_sym, meth
292
+ class_eval <<-EOD
293
+ def #{meth}(*args, &block)
294
+ Debugger.start do |dbg|
295
+ dbg.post_mortem do
296
+ #{old_meth}(*args, &block)
297
+ end
298
+ end
299
+ end
300
+ EOD
301
+ end
302
+ end
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+
4
+ # Some tests of Debugger module in C extension ruby_debug
5
+ class TestRubyDebug < Test::Unit::TestCase
6
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'ext')
7
+ require 'ruby_debug'
8
+ $:.shift
9
+
10
+ # test current_context
11
+ def test_current_context
12
+ assert_equal(false, Debugger.started?,
13
+ 'debugger should not initially be started.')
14
+ Debugger.start_
15
+ assert(Debugger.started?,
16
+ 'debugger should now be started.')
17
+ assert_equal(__LINE__, Debugger.current_context.frame_line)
18
+ assert_equal(nil, Debugger.current_context.frame_args_info,
19
+ 'no frame args info.')
20
+ assert_equal(Debugger.current_context.frame_file,
21
+ Debugger.current_context.frame_file(0))
22
+ assert_equal(File.basename(__FILE__),
23
+ File.basename(Debugger.current_context.frame_file))
24
+ assert_raises(ArgumentError) {Debugger.current_context.frame_file(1, 2)}
25
+ assert_raises(ArgumentError) {Debugger.current_context.frame_file(10)}
26
+ assert_equal(1, Debugger.current_context.stack_size)
27
+ assert_equal(TestRubyDebug, Debugger.current_context.frame_class)
28
+ assert_equal(false, Debugger.current_context.dead?, 'Not dead yet!')
29
+ Debugger.stop
30
+ assert_equal(false, Debugger.started?,
31
+ 'Debugger should no longer be started.')
32
+ end
33
+
34
+ # Test initial variables and setting/getting state.
35
+ def test_debugger_base
36
+ assert_equal(false, Debugger.started?,
37
+ 'Debugger should not initially be started.')
38
+ Debugger.start_
39
+ assert(Debugger.started?,
40
+ 'Debugger should now be started.')
41
+ assert_equal(false, Debugger.debug,
42
+ 'Debug variable should not be set.')
43
+ assert_equal(false, Debugger.post_mortem?,
44
+ 'Post mortem debugging should not be set.')
45
+ a = Debugger.contexts
46
+ assert_equal(1, a.size,
47
+ 'There should only be one context.')
48
+ assert_equal(Array, a.class,
49
+ 'Context should be an array.')
50
+ Debugger.stop
51
+ assert_equal(false, Debugger.started?,
52
+ 'debugger should no longer be started.')
53
+ end
54
+
55
+ # Test breakpoint handling
56
+ def test_breakpoints
57
+ Debugger.start_
58
+ assert_equal(0, Debugger.breakpoints.size,
59
+ 'There should not be any breakpoints set.')
60
+ brk = Debugger.add_breakpoint(__FILE__, 1)
61
+ assert_equal(Debugger::Breakpoint, brk.class,
62
+ 'Breakpoint should have been set and returned.')
63
+ assert_equal(1, Debugger.breakpoints.size,
64
+ 'There should now be one breakpoint set.')
65
+ Debugger.remove_breakpoint(0)
66
+ assert_equal(1, Debugger.breakpoints.size,
67
+ 'There should still be one breakpoint set.')
68
+ Debugger.remove_breakpoint(1)
69
+ assert_equal(0, Debugger.breakpoints.size,
70
+ 'There should no longer be any breakpoints set.')
71
+ Debugger.stop
72
+ end
73
+ end
74
+
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+
5
+ # Test binding_n command
6
+ class TestBinding < Test::Unit::TestCase
7
+
8
+ SRC_DIR = File.expand_path(File.dirname(__FILE__)) unless
9
+ defined?(SRC_DIR)
10
+ %w(ext lib).each do |dir|
11
+ $:.unshift File.join(SRC_DIR, '..', '..', dir)
12
+ end
13
+ require File.join(SRC_DIR, '..', '..', 'lib', 'ruby-debug-base')
14
+ $:.shift; $:.shift
15
+
16
+ def test_basic
17
+ def inside_fn
18
+ s = 'some other string'
19
+ b2 = Kernel::binding_n(1)
20
+ y2 = eval('s', b2)
21
+ assert_equal('this is a test', y2)
22
+ end
23
+ s = 'this is a test'
24
+ Debugger.start
25
+ b = Kernel::binding_n(0)
26
+ y = eval('s', b)
27
+ assert_equal(y, s)
28
+ inside_fn
29
+ Debugger.stop
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+
4
+ # Test catchpoint in C ruby_debug extension.
5
+
6
+ class TestRubyDebugCatchpoint < Test::Unit::TestCase
7
+
8
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'ext')
9
+ require 'ruby_debug'
10
+ $:.shift
11
+
12
+ # test current_context
13
+ def test_catchpoints
14
+ assert_raise(RuntimeError) {Debugger.catchpoints}
15
+ Debugger.start_
16
+ assert_equal({}, Debugger.catchpoints)
17
+ Debugger.add_catchpoint('ZeroDivisionError')
18
+ assert_equal({'ZeroDivisionError' => 0}, Debugger.catchpoints)
19
+ Debugger.add_catchpoint('RuntimeError')
20
+ assert_equal(['RuntimeError', 'ZeroDivisionError'],
21
+ Debugger.catchpoints.keys.sort)
22
+ Debugger.stop
23
+ end
24
+
25
+ end
26
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-debug-base19
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.11.15
5
+ platform: ruby
6
+ authors:
7
+ - Kent Sibilev
8
+ - Mark Moseley
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-08-24 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: columnize
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.3.1
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: ruby_core_source
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.1.4
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: linecache19
38
+ type: :runtime
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 0.5.11
45
+ version:
46
+ description: |
47
+ ruby-debug is a fast implementation of the standard Ruby debugger debug.rb.
48
+ It is implemented by utilizing a new Ruby C API hook. The core component
49
+ provides support that front-ends can build on. It provides breakpoint
50
+ handling, bindings for stack frames among other things.
51
+
52
+ email: mark@fast-software.com
53
+ executables: []
54
+
55
+ extensions:
56
+ - ext/ruby_debug/extconf.rb
57
+ extra_rdoc_files:
58
+ - README
59
+ - ext/ruby_debug/ruby_debug.c
60
+ files:
61
+ - AUTHORS
62
+ - CHANGES
63
+ - LICENSE
64
+ - README
65
+ - Rakefile
66
+ - ext/ruby_debug/extconf.rb
67
+ - ext/ruby_debug/breakpoint.c
68
+ - ext/ruby_debug/ruby_debug.h
69
+ - ext/ruby_debug/ruby_debug.c
70
+ - lib/ruby-debug-base.rb
71
+ - lib/ChangeLog
72
+ - test/base/base.rb
73
+ - test/base/binding.rb
74
+ - test/base/catchpoint.rb
75
+ has_rdoc: true
76
+ homepage: http://rubyforge.org/projects/ruby-debug19/
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options:
81
+ - --charset=UTF-8
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.8.2
89
+ version:
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ version:
96
+ requirements: []
97
+
98
+ rubyforge_project: ruby-debug19
99
+ rubygems_version: 1.3.4
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Fast Ruby debugger - core component
103
+ test_files:
104
+ - test/base/base.rb
105
+ - test/base/binding.rb
106
+ - test/base/catchpoint.rb