ruby-debug 0.4.5-mswin32 → 0.5-mswin32
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/bin/rdebug +12 -9
- data/ext/ruby_debug.c +50 -7
- data/lib/ruby-debug.rb +67 -15
- data/lib/ruby-debug/command.rb +1 -0
- data/lib/ruby-debug/commands/control.rb +1 -0
- data/lib/ruby-debug/commands/frame.rb +5 -5
- data/lib/ruby-debug/commands/irb.rb +50 -0
- data/lib/ruby-debug/commands/list.rb +5 -5
- data/lib/ruby-debug/commands/stepping.rb +14 -14
- data/lib/ruby-debug/commands/threads.rb +8 -0
- data/lib/ruby-debug/commands/tmate.rb +2 -2
- data/lib/ruby-debug/processor.rb +20 -6
- data/lib/ruby_debug.so +0 -0
- metadata +3 -2
data/bin/rdebug
CHANGED
@@ -6,14 +6,15 @@ require "ostruct"
|
|
6
6
|
require 'ruby-debug'
|
7
7
|
|
8
8
|
options = OpenStruct.new(
|
9
|
-
'server'
|
10
|
-
'client'
|
11
|
-
'host'
|
12
|
-
'port'
|
13
|
-
'cport'
|
14
|
-
'wait'
|
15
|
-
'nostop'
|
16
|
-
'
|
9
|
+
'server' => false,
|
10
|
+
'client' => false,
|
11
|
+
'host' => nil,
|
12
|
+
'port' => Debugger::PORT,
|
13
|
+
'cport' => Debugger::PORT + 1,
|
14
|
+
'wait' => false,
|
15
|
+
'nostop' => false,
|
16
|
+
'post_mortem' => false,
|
17
|
+
'script' => nil
|
17
18
|
)
|
18
19
|
|
19
20
|
opts = OptionParser.new do |opts|
|
@@ -26,6 +27,7 @@ EOB
|
|
26
27
|
opts.on("-s", "--server", "Listen for remote connections") {options.server = true}
|
27
28
|
opts.on("-w", "--wait", "Wait for a client connection, implies -s option") {options.wait = true}
|
28
29
|
opts.on("-n", "--nostop", "Do not stop when a client connects, implies -s option") {options.nostop = true}
|
30
|
+
opts.on("-m", "--post-mortem", "Activate post-mortem mode") {options.post_mortem = true}
|
29
31
|
opts.on("-c", "--client", "Connect to remote debugger") {options.client = true}
|
30
32
|
opts.on("-h", "--host HOST", "Host name used for remote debugging") {|options.host|}
|
31
33
|
opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|options.port|}
|
@@ -75,13 +77,14 @@ else
|
|
75
77
|
Debugger.wait_connection = options.wait
|
76
78
|
load "#{ENV["HOME"]}/.rdebugrc" if File.exists?("#{ENV["HOME"]}/.rdebugrc")
|
77
79
|
if options.server
|
78
|
-
Debugger.start_remote(options.host, [options.port, options.cport])
|
80
|
+
Debugger.start_remote(options.host, [options.port, options.cport], options.post_mortem)
|
79
81
|
Debugger.debug_load ARGV.shift
|
80
82
|
else
|
81
83
|
Debugger.start
|
82
84
|
if options.script
|
83
85
|
Debugger.run_script(options.script)
|
84
86
|
end
|
87
|
+
Debugger.post_mortem if options.post_mortem
|
85
88
|
debugger 2
|
86
89
|
Debugger.debug_load ARGV.shift
|
87
90
|
end
|
data/ext/ruby_debug.c
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#include <rubysig.h>
|
5
5
|
#include <st.h>
|
6
6
|
|
7
|
-
#define DEBUG_VERSION "0.
|
7
|
+
#define DEBUG_VERSION "0.5"
|
8
8
|
|
9
9
|
#define CTX_FL_MOVED (1<<1)
|
10
10
|
#define CTX_FL_SUSPEND (1<<2)
|
@@ -57,6 +57,7 @@ static VALUE breakpoints = Qnil;
|
|
57
57
|
static VALUE catchpoint = Qnil;
|
58
58
|
static VALUE tracing = Qfalse;
|
59
59
|
static VALUE locker = Qnil;
|
60
|
+
static VALUE post_mortem = Qfalse;
|
60
61
|
|
61
62
|
static VALUE mDebugger;
|
62
63
|
static VALUE cThreadsTable;
|
@@ -472,7 +473,8 @@ check_breakpoint_expression(VALUE breakpoint, VALUE binding)
|
|
472
473
|
static void
|
473
474
|
debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
474
475
|
{
|
475
|
-
VALUE thread, context,
|
476
|
+
VALUE thread, context, breakpoint;
|
477
|
+
VALUE binding = Qnil;
|
476
478
|
debug_context_t *debug_context;
|
477
479
|
VALUE file = Qnil, line = Qnil;
|
478
480
|
int breakpoint_index = -1;
|
@@ -621,6 +623,16 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
621
623
|
VALUE ancestors;
|
622
624
|
VALUE expn_class, aclass;
|
623
625
|
int i;
|
626
|
+
|
627
|
+
if(post_mortem == Qtrue && self)
|
628
|
+
{
|
629
|
+
binding = create_binding(self);
|
630
|
+
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_binding"), binding);
|
631
|
+
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_file"), file);
|
632
|
+
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_line"), line);
|
633
|
+
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_binding"), binding);
|
634
|
+
rb_ivar_set(ruby_errinfo, rb_intern("@__debug_frames"), rb_obj_dup(debug_context->frames));
|
635
|
+
}
|
624
636
|
|
625
637
|
expn_class = rb_obj_class(ruby_errinfo);
|
626
638
|
if( !NIL_P(rb_class_inherited_p(expn_class, rb_eSystemExit)) )
|
@@ -639,7 +651,8 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
639
651
|
if(rb_str_cmp(rb_mod_name(aclass), catchpoint) == 0)
|
640
652
|
{
|
641
653
|
rb_funcall(context, idAtCatchpoint, 1, ruby_errinfo);
|
642
|
-
|
654
|
+
if(self && binding == Qnil)
|
655
|
+
binding = create_binding(self);
|
643
656
|
call_at_line(context, debug_context->thnum, binding, file, line);
|
644
657
|
break;
|
645
658
|
}
|
@@ -703,7 +716,7 @@ debug_start(VALUE self)
|
|
703
716
|
}
|
704
717
|
|
705
718
|
if(rb_block_given_p())
|
706
|
-
return rb_ensure(rb_yield,
|
719
|
+
return rb_ensure(rb_yield, self, debug_stop_i, self);
|
707
720
|
return result;
|
708
721
|
}
|
709
722
|
|
@@ -1002,7 +1015,7 @@ debug_resume(VALUE self)
|
|
1002
1015
|
* call-seq:
|
1003
1016
|
* Debugger.tracing -> bool
|
1004
1017
|
*
|
1005
|
-
* Returns +true+
|
1018
|
+
* Returns +true+ if the global tracing is activated.
|
1006
1019
|
*/
|
1007
1020
|
static VALUE
|
1008
1021
|
debug_tracing(VALUE self)
|
@@ -1014,7 +1027,7 @@ debug_tracing(VALUE self)
|
|
1014
1027
|
* call-seq:
|
1015
1028
|
* Debugger.tracing = bool
|
1016
1029
|
*
|
1017
|
-
* Sets
|
1030
|
+
* Sets the global tracing flag.
|
1018
1031
|
*/
|
1019
1032
|
static VALUE
|
1020
1033
|
debug_set_tracing(VALUE self, VALUE value)
|
@@ -1023,12 +1036,40 @@ debug_set_tracing(VALUE self, VALUE value)
|
|
1023
1036
|
return value;
|
1024
1037
|
}
|
1025
1038
|
|
1039
|
+
/*
|
1040
|
+
* call-seq:
|
1041
|
+
* Debugger.post_mortem? -> bool
|
1042
|
+
*
|
1043
|
+
* Returns +true+ if post-moterm debugging is enabled.
|
1044
|
+
*/
|
1045
|
+
static VALUE
|
1046
|
+
debug_post_mortem(VALUE self)
|
1047
|
+
{
|
1048
|
+
return post_mortem;
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
/*
|
1052
|
+
* call-seq:
|
1053
|
+
* Debugger.post_mortem = bool
|
1054
|
+
*
|
1055
|
+
* Sets post-moterm flag.
|
1056
|
+
* FOR INTERNAL USE ONLY.
|
1057
|
+
*/
|
1058
|
+
static VALUE
|
1059
|
+
debug_set_post_mortem(VALUE self, VALUE value)
|
1060
|
+
{
|
1061
|
+
debug_check_started();
|
1062
|
+
|
1063
|
+
post_mortem = RTEST(value) ? Qtrue : Qfalse;
|
1064
|
+
return value;
|
1065
|
+
}
|
1066
|
+
|
1026
1067
|
/*
|
1027
1068
|
* call-seq:
|
1028
1069
|
* Debugger.debug_load(file) -> nil
|
1029
1070
|
*
|
1030
1071
|
* Same as Kernel#load but resets current context's frames.
|
1031
|
-
* FOR INTERNAL USE ONLY.
|
1072
|
+
* FOR INTERNAL USE ONLY. Use Debugger.post_mortem method instead.
|
1032
1073
|
*/
|
1033
1074
|
static VALUE
|
1034
1075
|
debug_debug_load(VALUE self, VALUE file)
|
@@ -1556,6 +1597,8 @@ Init_ruby_debug()
|
|
1556
1597
|
rb_define_module_function(mDebugger, "debug_load", debug_debug_load, 1);
|
1557
1598
|
rb_define_module_function(mDebugger, "skip", debug_skip, 0);
|
1558
1599
|
rb_define_module_function(mDebugger, "debug_at_exit", debug_at_exit, 0);
|
1600
|
+
rb_define_module_function(mDebugger, "post_mortem?", debug_post_mortem, 0);
|
1601
|
+
rb_define_module_function(mDebugger, "post_mortem=", debug_set_post_mortem, 1);
|
1559
1602
|
|
1560
1603
|
cThreadsTable = rb_define_class_under(mDebugger, "ThreadsTable", rb_cObject);
|
1561
1604
|
|
data/lib/ruby-debug.rb
CHANGED
@@ -81,12 +81,13 @@ module Debugger
|
|
81
81
|
#
|
82
82
|
# Starts a remote debugger.
|
83
83
|
#
|
84
|
-
def start_remote(host = nil, port = PORT)
|
84
|
+
def start_remote(host = nil, port = PORT, post_mortem = false)
|
85
85
|
return if @thread
|
86
86
|
return if started?
|
87
87
|
|
88
88
|
self.interface = nil
|
89
89
|
start
|
90
|
+
self.post_mortem if post_mortem
|
90
91
|
|
91
92
|
require "socket"
|
92
93
|
|
@@ -169,21 +170,23 @@ module Debugger
|
|
169
170
|
private :stop_main_thread
|
170
171
|
|
171
172
|
def source_for(file) # :nodoc:
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
SCRIPT_LINES__[file]
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
173
|
+
Dir.chdir File.dirname($0) do
|
174
|
+
unless File.exists?(file)
|
175
|
+
return (SCRIPT_LINES__[file] == true ? nil : SCRIPT_LINES__[file])
|
176
|
+
end
|
177
|
+
|
178
|
+
if SCRIPT_LINES__[file].nil? || SCRIPT_LINES__[file] == true
|
179
|
+
SCRIPT_LINES__[file] = File.readlines(file)
|
180
|
+
end
|
181
|
+
|
182
|
+
change_time = test(?M, file)
|
183
|
+
SCRIPT_TIMESTAMPS__[file] ||= change_time
|
184
|
+
if @reload_source_on_change && SCRIPT_TIMESTAMPS__[file] < change_time
|
185
|
+
SCRIPT_LINES__[file] = File.readlines(file)
|
186
|
+
end
|
187
|
+
|
188
|
+
SCRIPT_LINES__[file]
|
184
189
|
end
|
185
|
-
|
186
|
-
SCRIPT_LINES__[file]
|
187
190
|
end
|
188
191
|
|
189
192
|
def source_reload
|
@@ -211,9 +214,58 @@ module Debugger
|
|
211
214
|
processor = ControlCommandProcessor.new(interface)
|
212
215
|
processor.process_commands
|
213
216
|
end
|
217
|
+
|
218
|
+
#
|
219
|
+
# Activates the post-mortem mode. There are two ways of using it:
|
220
|
+
#
|
221
|
+
# == Global post-mortem mode
|
222
|
+
# By calling Debugger.post_mortem method without a block, you install
|
223
|
+
# at_exit hook that intercepts any unhandled by your script exceptions
|
224
|
+
# and enables post-mortem mode.
|
225
|
+
#
|
226
|
+
# == Local post-mortem mode
|
227
|
+
#
|
228
|
+
# If you know that a particular block of code raises an exception you can
|
229
|
+
# enable post-mortem mode by wrapping this block with Debugger.post_mortem, e.g.
|
230
|
+
#
|
231
|
+
# def offender
|
232
|
+
# raise 'error'
|
233
|
+
# end
|
234
|
+
# Debugger.post_mortem do
|
235
|
+
# ...
|
236
|
+
# offender
|
237
|
+
# ...
|
238
|
+
# end
|
239
|
+
def post_mortem
|
240
|
+
raise "Post-mortem is already activated" if self.post_mortem?
|
241
|
+
self.post_mortem = true
|
242
|
+
if block_given?
|
243
|
+
begin
|
244
|
+
yield
|
245
|
+
rescue Exception => exp
|
246
|
+
handle_post_mortem(exp)
|
247
|
+
raise
|
248
|
+
ensure
|
249
|
+
self.post_mortem = false
|
250
|
+
end
|
251
|
+
else
|
252
|
+
debug_at_exit do
|
253
|
+
handle_post_mortem($!) if $! && post_mortem?
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def handle_post_mortem(exp)
|
259
|
+
processor.at_line(nil, exp.__debug_file, exp.__debug_line, exp.__debug_binding, exp.__debug_frames)
|
260
|
+
end
|
261
|
+
private :handle_post_mortem
|
214
262
|
end
|
215
263
|
end
|
216
264
|
|
265
|
+
class Exception # :nodoc:
|
266
|
+
attr_reader :__debug_file, :__debug_line, :__debug_binding, :__debug_frames
|
267
|
+
end
|
268
|
+
|
217
269
|
module Kernel
|
218
270
|
#
|
219
271
|
# Stops the current thread after a number of _steps_ made.
|
data/lib/ruby-debug/command.rb
CHANGED
@@ -14,7 +14,7 @@ module Debugger
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def execute
|
17
|
-
@state.
|
17
|
+
@state.frames.each_with_index do |frame, idx|
|
18
18
|
if idx == @state.frame_pos
|
19
19
|
print "--> "
|
20
20
|
else
|
@@ -63,11 +63,11 @@ module Debugger
|
|
63
63
|
@state.frame_pos += (arg ? arg.to_i : 1)
|
64
64
|
end
|
65
65
|
@state.frame_pos = 0 if @state.frame_pos < 0
|
66
|
-
if @state.frame_pos >= @state.
|
67
|
-
@state.frame_pos = @state.
|
66
|
+
if @state.frame_pos >= @state.frames.size
|
67
|
+
@state.frame_pos = @state.frames.size - 1
|
68
68
|
print "At toplevel\n"
|
69
69
|
end
|
70
|
-
frame = @state.
|
70
|
+
frame = @state.frames[@state.frame_pos]
|
71
71
|
@state.binding, @state.file, @state.line = frame.binding, frame.file, frame.line
|
72
72
|
print format_frame(frame, @state.frame_pos)
|
73
73
|
end
|
@@ -105,7 +105,7 @@ module Debugger
|
|
105
105
|
@state.frame_pos = 0
|
106
106
|
print "At stack bottom\n"
|
107
107
|
end
|
108
|
-
frame = @state.
|
108
|
+
frame = @state.frames[@state.frame_pos]
|
109
109
|
@state.binding, @state.file, @state.line = frame.binding, frame.file, frame.line
|
110
110
|
print format_frame(frame, @state.frame_pos)
|
111
111
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'irb'
|
2
|
+
module IRB # :nodoc:
|
3
|
+
def self.start_session(binding)
|
4
|
+
IRB.setup(nil)
|
5
|
+
|
6
|
+
workspace = WorkSpace.new(binding)
|
7
|
+
|
8
|
+
irb = Irb.new(workspace)
|
9
|
+
|
10
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
11
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
12
|
+
|
13
|
+
# trap("SIGINT") do
|
14
|
+
# irb.signal_handle
|
15
|
+
# end
|
16
|
+
|
17
|
+
catch(:IRB_EXIT) do
|
18
|
+
irb.eval_input
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Debugger
|
24
|
+
class IRBCommand < Command # :nodoc:
|
25
|
+
def regexp
|
26
|
+
/^irb$/
|
27
|
+
end
|
28
|
+
|
29
|
+
def execute
|
30
|
+
unless @state.interface.kind_of?(LocalInterface)
|
31
|
+
print "Command is available only in local mode.\n"
|
32
|
+
return
|
33
|
+
end
|
34
|
+
IRB.start_session(@state.binding)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
def help_command
|
40
|
+
'irb'
|
41
|
+
end
|
42
|
+
|
43
|
+
def help(cmd)
|
44
|
+
%{
|
45
|
+
irb\tstarts an IRB session. (EXPERIMENTAL)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Debugger
|
2
2
|
class ListCommand < Command # :nodoc:
|
3
3
|
def regexp
|
4
|
-
/^\s*l(?:ist)?(?:\s*(.+))?$/
|
4
|
+
/^\s*l(?:ist)?(?:\s*([-=])|\s+(.+))?$/
|
5
5
|
end
|
6
6
|
|
7
7
|
def execute
|
8
|
-
if !@match ||
|
8
|
+
if !@match || !(@match[1] || @match[2])
|
9
9
|
b = @state.previous_line ? @state.previous_line + 10 : @state.line - 5
|
10
10
|
e = b + 9
|
11
11
|
elsif @match[1] == '-'
|
@@ -15,16 +15,16 @@ module Debugger
|
|
15
15
|
@state.previous_line = nil
|
16
16
|
b = @state.line - 5
|
17
17
|
e = b + 9
|
18
|
-
elsif @match[
|
18
|
+
elsif @match[2] == 'on'
|
19
19
|
self.class.always_run = true
|
20
20
|
print "Listing is on.\n"
|
21
21
|
return
|
22
|
-
elsif @match[
|
22
|
+
elsif @match[2] == 'off'
|
23
23
|
self.class.always_run = false
|
24
24
|
print "Listing is off.\n"
|
25
25
|
return
|
26
26
|
else
|
27
|
-
b, e = @match[
|
27
|
+
b, e = @match[2].split(/[-,]/)
|
28
28
|
if e
|
29
29
|
b = b.to_i
|
30
30
|
e = e.to_i
|
@@ -1,12 +1,14 @@
|
|
1
1
|
module Debugger
|
2
2
|
class NextCommand < Command # :nodoc:
|
3
|
+
self.context = true
|
4
|
+
|
3
5
|
def regexp
|
4
6
|
/^\s*n(?:ext)?(?:\s+(\d+))?$/
|
5
7
|
end
|
6
8
|
|
7
9
|
def execute
|
8
10
|
steps = @match[1] ? @match[1].to_i : 1
|
9
|
-
@state.context.step_over steps, @state.
|
11
|
+
@state.context.step_over steps, @state.frames.size - @state.frame_pos
|
10
12
|
@state.proceed
|
11
13
|
end
|
12
14
|
|
@@ -24,6 +26,8 @@ module Debugger
|
|
24
26
|
end
|
25
27
|
|
26
28
|
class StepCommand < Command # :nodoc:
|
29
|
+
self.context = true
|
30
|
+
|
27
31
|
def regexp
|
28
32
|
/^\s*s(?:tep)?(?:\s+(\d+))?$/
|
29
33
|
end
|
@@ -47,15 +51,17 @@ module Debugger
|
|
47
51
|
end
|
48
52
|
|
49
53
|
class FinishCommand < Command # :nodoc:
|
54
|
+
self.context = true
|
55
|
+
|
50
56
|
def regexp
|
51
57
|
/^\s*fin(?:ish)?$/
|
52
58
|
end
|
53
59
|
|
54
60
|
def execute
|
55
|
-
if @state.frame_pos == @state.
|
61
|
+
if @state.frame_pos == @state.frames.size
|
56
62
|
print "\"finish\" not meaningful in the outermost frame.\n"
|
57
63
|
else
|
58
|
-
@state.context.stop_frame = @state.
|
64
|
+
@state.context.stop_frame = @state.frames.size - @state.frame_pos
|
59
65
|
@state.frame_pos = 0
|
60
66
|
@state.proceed
|
61
67
|
end
|
@@ -76,7 +82,7 @@ module Debugger
|
|
76
82
|
|
77
83
|
class ContinueCommand < Command # :nodoc:
|
78
84
|
def regexp
|
79
|
-
/^\s*c(?:ont)
|
85
|
+
/^\s*c(?:ont)?$/
|
80
86
|
end
|
81
87
|
|
82
88
|
def execute
|
@@ -85,19 +91,13 @@ module Debugger
|
|
85
91
|
|
86
92
|
class << self
|
87
93
|
def help_command
|
88
|
-
|
94
|
+
'cont'
|
89
95
|
end
|
90
96
|
|
91
97
|
def help(cmd)
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
}
|
96
|
-
else
|
97
|
-
%{
|
98
|
-
r[un]\talias for cont
|
99
|
-
}
|
100
|
-
end
|
98
|
+
%{
|
99
|
+
c[ont]\trun until program ends or hit breakpoint
|
100
|
+
}
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -47,6 +47,8 @@ module Debugger
|
|
47
47
|
|
48
48
|
class ThreadSwitchCommand < Command # :nodoc:
|
49
49
|
self.control = true
|
50
|
+
self.context = true
|
51
|
+
|
50
52
|
include ThreadFunctions
|
51
53
|
|
52
54
|
def regexp
|
@@ -83,6 +85,8 @@ module Debugger
|
|
83
85
|
|
84
86
|
class ThreadStopCommand < Command # :nodoc:
|
85
87
|
self.control = true
|
88
|
+
self.context = true
|
89
|
+
|
86
90
|
include ThreadFunctions
|
87
91
|
|
88
92
|
def regexp
|
@@ -118,6 +122,8 @@ module Debugger
|
|
118
122
|
end
|
119
123
|
|
120
124
|
class ThreadCurrentCommand < Command # :nodoc:
|
125
|
+
self.context = true
|
126
|
+
|
121
127
|
include ThreadFunctions
|
122
128
|
|
123
129
|
def regexp
|
@@ -143,6 +149,8 @@ module Debugger
|
|
143
149
|
|
144
150
|
class ThreadResumeCommand < Command # :nodoc:
|
145
151
|
self.control = true
|
152
|
+
self.context = true
|
153
|
+
|
146
154
|
include ThreadFunctions
|
147
155
|
|
148
156
|
def regexp
|
@@ -8,11 +8,11 @@ module Debugger
|
|
8
8
|
def execute
|
9
9
|
if @match[1]
|
10
10
|
frm_n = @match[1].to_i
|
11
|
-
if frm_n > @state.
|
11
|
+
if frm_n > @state.frames.size || frm_n == 0
|
12
12
|
print "Wrong frame number\n"
|
13
13
|
return
|
14
14
|
end
|
15
|
-
frame = @state.
|
15
|
+
frame = @state.frames[frm_n - 1]
|
16
16
|
file, line = frame.file, frame.line
|
17
17
|
else
|
18
18
|
file, line = @state.file, @state.line
|
data/lib/ruby-debug/processor.rb
CHANGED
@@ -61,9 +61,9 @@ module Debugger
|
|
61
61
|
end
|
62
62
|
protect :at_tracing
|
63
63
|
|
64
|
-
def at_line(context, file, line, binding)
|
64
|
+
def at_line(context, file, line, binding, frames = context.frames)
|
65
65
|
print "%s:%d: %s", file, line, Debugger.line_at(file, line)
|
66
|
-
process_commands(context, file, line, binding)
|
66
|
+
process_commands(context, file, line, binding, frames)
|
67
67
|
end
|
68
68
|
protect :at_line
|
69
69
|
|
@@ -73,7 +73,15 @@ module Debugger
|
|
73
73
|
@interface.print(*args)
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
76
|
+
def prompt(context)
|
77
|
+
if context
|
78
|
+
"(rdb:%d) " % context.thnum
|
79
|
+
else
|
80
|
+
"(rdb:post-mortem) "
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def process_commands(context, file, line, binding, frames)
|
77
85
|
event_cmds = Command.commands.select{|cmd| cmd.event }
|
78
86
|
state = State.new do |s|
|
79
87
|
s.context = context
|
@@ -83,12 +91,14 @@ module Debugger
|
|
83
91
|
s.display = display
|
84
92
|
s.interface = interface
|
85
93
|
s.commands = event_cmds
|
94
|
+
s.frames = frames
|
86
95
|
end
|
87
96
|
commands = event_cmds.map{|cmd| cmd.new(state) }
|
88
97
|
commands.select{|cmd| cmd.class.always_run }.each{|cmd| cmd.execute }
|
89
98
|
|
90
|
-
while !state.proceed? and input = @interface.read_command(
|
99
|
+
while !state.proceed? and input = @interface.read_command(prompt(context))
|
91
100
|
catch(:debug_error) do
|
101
|
+
|
92
102
|
if input == ""
|
93
103
|
next unless @last_cmd
|
94
104
|
input = @last_cmd
|
@@ -97,7 +107,11 @@ module Debugger
|
|
97
107
|
end
|
98
108
|
|
99
109
|
if cmd = commands.find{ |c| c.match(input) }
|
100
|
-
cmd.
|
110
|
+
if context.nil? && cmd.class.context
|
111
|
+
print "Command is unavailable\n"
|
112
|
+
else
|
113
|
+
cmd.execute
|
114
|
+
end
|
101
115
|
else
|
102
116
|
unknown_cmd = commands.find{|cmd| cmd.class.unknown }
|
103
117
|
if unknown_cmd
|
@@ -113,7 +127,7 @@ module Debugger
|
|
113
127
|
class State # :nodoc:
|
114
128
|
attr_accessor :context, :file, :line, :binding
|
115
129
|
attr_accessor :frame_pos, :previous_line, :display
|
116
|
-
attr_accessor :interface, :commands
|
130
|
+
attr_accessor :interface, :commands, :frames
|
117
131
|
|
118
132
|
def initialize
|
119
133
|
@frame_pos = 0
|
data/lib/ruby_debug.so
CHANGED
Binary file
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-debug
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-12-
|
6
|
+
version: "0.5"
|
7
|
+
date: 2006-12-20 16:26:41 -05:00
|
8
8
|
summary: Fast Ruby debugger
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- lib/ruby-debug/commands/eval.rb
|
47
47
|
- lib/ruby-debug/commands/frame.rb
|
48
48
|
- lib/ruby-debug/commands/help.rb
|
49
|
+
- lib/ruby-debug/commands/irb.rb
|
49
50
|
- lib/ruby-debug/commands/list.rb
|
50
51
|
- lib/ruby-debug/commands/method.rb
|
51
52
|
- lib/ruby-debug/commands/script.rb
|