byebug 2.7.0 → 3.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -6
- data/.travis.yml +1 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile +9 -0
- data/README.md +35 -32
- data/Rakefile +1 -3
- data/byebug.gemspec +0 -6
- data/ext/byebug/byebug.c +64 -51
- data/ext/byebug/byebug.h +12 -13
- data/ext/byebug/context.c +28 -43
- data/ext/byebug/extconf.rb +6 -6
- data/lib/byebug.rb +34 -38
- data/lib/byebug/command.rb +4 -2
- data/lib/byebug/commands/continue.rb +0 -1
- data/lib/byebug/commands/control.rb +0 -1
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/finish.rb +10 -16
- data/lib/byebug/commands/help.rb +1 -1
- data/lib/byebug/commands/kill.rb +1 -1
- data/lib/byebug/commands/quit.rb +1 -1
- data/lib/byebug/commands/repl.rb +3 -3
- data/lib/byebug/commands/set.rb +24 -39
- data/lib/byebug/commands/show.rb +39 -112
- data/lib/byebug/commands/stepping.rb +0 -2
- data/lib/byebug/commands/threads.rb +0 -5
- data/lib/byebug/commands/trace.rb +1 -1
- data/lib/byebug/commands/variables.rb +1 -1
- data/lib/byebug/context.rb +8 -12
- data/lib/byebug/helper.rb +1 -1
- data/lib/byebug/history.rb +46 -0
- data/lib/byebug/interface.rb +5 -5
- data/lib/byebug/interfaces/local_interface.rb +11 -62
- data/lib/byebug/interfaces/remote_interface.rb +6 -22
- data/lib/byebug/interfaces/script_interface.rb +2 -17
- data/lib/byebug/processor.rb +4 -4
- data/lib/byebug/{command_processor.rb → processors/command_processor.rb} +7 -14
- data/lib/byebug/{control_command_processor.rb → processors/control_command_processor.rb} +3 -7
- data/lib/byebug/version.rb +1 -1
- data/test/edit_test.rb +6 -6
- data/test/examples/breakpoint_deep.rb +1 -1
- data/test/finish_test.rb +6 -6
- data/test/help_test.rb +1 -1
- data/test/info_test.rb +0 -1
- data/test/kill_test.rb +2 -2
- data/test/post_mortem_test.rb +35 -219
- data/test/quit_test.rb +2 -2
- data/test/restart_test.rb +12 -33
- data/test/set_test.rb +80 -107
- data/test/show_test.rb +42 -77
- data/test/stepping_test.rb +1 -1
- data/test/support/test_dsl.rb +4 -25
- data/test/support/test_interface.rb +40 -48
- data/test/test_helper.rb +1 -3
- data/test/timeout_test.rb +9 -0
- metadata +8 -75
data/ext/byebug/context.c
CHANGED
@@ -12,8 +12,7 @@ reset_stepping_stop_points(debug_context_t *context)
|
|
12
12
|
context->dest_frame = -1;
|
13
13
|
context->lines = -1;
|
14
14
|
context->steps = -1;
|
15
|
-
context->
|
16
|
-
context->before_frame = -1;
|
15
|
+
context->steps_out = -1;
|
17
16
|
}
|
18
17
|
|
19
18
|
/*
|
@@ -38,16 +37,10 @@ context_mark(void *data)
|
|
38
37
|
rb_gc_mark(context->backtrace);
|
39
38
|
}
|
40
39
|
|
41
|
-
static void
|
42
|
-
context_free(void *data)
|
43
|
-
{
|
44
|
-
|
45
|
-
}
|
46
|
-
|
47
40
|
static int
|
48
41
|
real_stack_size()
|
49
42
|
{
|
50
|
-
return FIX2INT(rb_funcall(cContext, rb_intern("
|
43
|
+
return FIX2INT(rb_funcall(cContext, rb_intern("stack_size"), 1, Qtrue));
|
51
44
|
}
|
52
45
|
|
53
46
|
extern VALUE
|
@@ -67,7 +60,7 @@ context_create(VALUE thread)
|
|
67
60
|
|
68
61
|
if (rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE);
|
69
62
|
|
70
|
-
return Data_Wrap_Struct(cContext, context_mark,
|
63
|
+
return Data_Wrap_Struct(cContext, context_mark, 0, context);
|
71
64
|
}
|
72
65
|
|
73
66
|
extern VALUE
|
@@ -80,7 +73,7 @@ context_dup(debug_context_t *context)
|
|
80
73
|
new_context->backtrace = context->backtrace;
|
81
74
|
CTX_FL_SET(new_context, CTX_FL_DEAD);
|
82
75
|
|
83
|
-
return Data_Wrap_Struct(cContext, context_mark,
|
76
|
+
return Data_Wrap_Struct(cContext, context_mark, 0, new_context);
|
84
77
|
}
|
85
78
|
|
86
79
|
static VALUE
|
@@ -225,7 +218,7 @@ Context_frame_binding(int argc, VALUE *argv, VALUE self)
|
|
225
218
|
*
|
226
219
|
* Returns frame's defined class.
|
227
220
|
*/
|
228
|
-
|
221
|
+
static VALUE
|
229
222
|
Context_frame_class(int argc, VALUE *argv, VALUE self)
|
230
223
|
{
|
231
224
|
FRAME_SETUP
|
@@ -405,8 +398,7 @@ Context_stop_reason(VALUE self)
|
|
405
398
|
static VALUE
|
406
399
|
Context_step_into(int argc, VALUE *argv, VALUE self)
|
407
400
|
{
|
408
|
-
VALUE steps;
|
409
|
-
VALUE force;
|
401
|
+
VALUE steps, force;
|
410
402
|
debug_context_t *context;
|
411
403
|
|
412
404
|
rb_scan_args(argc, argv, "11", &steps, &force);
|
@@ -428,22 +420,35 @@ Context_step_into(int argc, VALUE *argv, VALUE self)
|
|
428
420
|
* call-seq:
|
429
421
|
* context.step_out(frame)
|
430
422
|
*
|
431
|
-
* Stops after
|
432
|
-
* +next+ commands.
|
423
|
+
* Stops after +n_frames+ frames are finished. Implements +finish+ and
|
424
|
+
* +next+ commands. +force+ parameter (if true) ensures that the cursor will
|
425
|
+
* stop in the specified frame even when there's no more instructions to run.
|
426
|
+
* In that case, it will stop when the return event for that frame is
|
427
|
+
* triggered.
|
433
428
|
*/
|
434
429
|
static VALUE
|
435
|
-
Context_step_out(VALUE
|
430
|
+
Context_step_out(int argc, VALUE *argv, VALUE self)
|
436
431
|
{
|
432
|
+
int n_args, n_frames;
|
433
|
+
VALUE v_frames, v_force;
|
437
434
|
debug_context_t *context;
|
438
435
|
|
436
|
+
n_args = rb_scan_args(argc, argv, "02", &v_frames, &v_force);
|
437
|
+
n_frames = n_args == 0 ? 1 : FIX2INT(v_frames);
|
438
|
+
v_force = (n_args < 2) ? Qfalse : v_force;
|
439
|
+
|
439
440
|
Data_Get_Struct(self, debug_context_t, context);
|
440
441
|
|
441
|
-
if (
|
442
|
+
if (n_frames < 0 || n_frames >= context->calced_stack_size)
|
442
443
|
rb_raise(rb_eRuntimeError, "Stop frame is out of range.");
|
443
444
|
|
444
|
-
context->
|
445
|
+
context->steps_out = n_frames;
|
446
|
+
if (RTEST(v_force))
|
447
|
+
CTX_FL_SET(context, CTX_FL_STOP_ON_RET);
|
448
|
+
else
|
449
|
+
CTX_FL_UNSET(context, CTX_FL_STOP_ON_RET);
|
445
450
|
|
446
|
-
return
|
451
|
+
return Qnil;
|
447
452
|
}
|
448
453
|
|
449
454
|
/*
|
@@ -481,27 +486,6 @@ Context_step_over(int argc, VALUE *argv, VALUE self)
|
|
481
486
|
return Qnil;
|
482
487
|
}
|
483
488
|
|
484
|
-
/*
|
485
|
-
* call-seq:
|
486
|
-
* context.stop_return(frame)
|
487
|
-
*
|
488
|
-
* Stops before frame number +frame+ is activated. Useful when you enter the
|
489
|
-
* debugger after the last statement in a method.
|
490
|
-
*/
|
491
|
-
static VALUE
|
492
|
-
Context_stop_return(VALUE self, VALUE frame)
|
493
|
-
{
|
494
|
-
debug_context_t *context;
|
495
|
-
|
496
|
-
Data_Get_Struct(self, debug_context_t, context);
|
497
|
-
if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size)
|
498
|
-
rb_raise(rb_eRuntimeError, "Stop frame is out of range.");
|
499
|
-
|
500
|
-
context->before_frame = context->calced_stack_size - FIX2INT(frame);
|
501
|
-
|
502
|
-
return frame;
|
503
|
-
}
|
504
|
-
|
505
489
|
static void
|
506
490
|
context_suspend_0(debug_context_t *context)
|
507
491
|
{
|
@@ -619,6 +603,8 @@ static VALUE
|
|
619
603
|
DebugThread_inherited(VALUE klass)
|
620
604
|
{
|
621
605
|
rb_raise(rb_eRuntimeError, "Can't inherit Byebug::DebugThread class");
|
606
|
+
|
607
|
+
return Qnil;
|
622
608
|
}
|
623
609
|
|
624
610
|
/*
|
@@ -644,9 +630,8 @@ Init_context(VALUE mByebug)
|
|
644
630
|
rb_define_method(cContext, "resume" , Context_resume , 0);
|
645
631
|
rb_define_method(cContext, "calced_stack_size", Context_calced_stack_size, 0);
|
646
632
|
rb_define_method(cContext, "step_into" , Context_step_into , -1);
|
647
|
-
rb_define_method(cContext, "step_out" , Context_step_out ,
|
633
|
+
rb_define_method(cContext, "step_out" , Context_step_out , -1);
|
648
634
|
rb_define_method(cContext, "step_over" , Context_step_over , -1);
|
649
|
-
rb_define_method(cContext, "stop_return" , Context_stop_return , 1);
|
650
635
|
rb_define_method(cContext, "stop_reason" , Context_stop_reason , 0);
|
651
636
|
rb_define_method(cContext, "suspend" , Context_suspend , 0);
|
652
637
|
rb_define_method(cContext, "suspended?" , Context_is_suspended , 0);
|
data/ext/byebug/extconf.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
4
|
-
|
5
|
-
if RUBY_VERSION < "2.0"
|
1
|
+
if RUBY_VERSION < '2.0'
|
6
2
|
STDERR.print("Ruby version is too old\n")
|
7
3
|
exit(1)
|
8
4
|
end
|
9
5
|
|
6
|
+
require 'mkmf'
|
7
|
+
|
8
|
+
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
9
|
+
|
10
10
|
if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
11
11
|
$CFLAGS ||= ''
|
12
12
|
$CFLAGS += ' -Wall -Werror -Wno-unused-parameter'
|
13
13
|
$CFLAGS += ' -gdwarf-2 -g3 -O0' if ENV['debug']
|
14
14
|
end
|
15
15
|
|
16
|
-
dir_config(
|
16
|
+
dir_config('ruby')
|
17
17
|
create_makefile('byebug/byebug')
|
data/lib/byebug.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'byebug/byebug'
|
2
2
|
require 'byebug/version'
|
3
3
|
require 'byebug/context'
|
4
|
+
require 'byebug/interface'
|
4
5
|
require 'byebug/processor'
|
5
|
-
require 'byebug/command_processor'
|
6
|
-
require 'byebug/control_command_processor'
|
7
6
|
require 'byebug/remote'
|
8
7
|
require 'stringio'
|
9
8
|
require 'tracer'
|
@@ -15,24 +14,26 @@ module Byebug
|
|
15
14
|
IGNORED_FILES = Dir.glob(File.expand_path('../**/*.rb', __FILE__))
|
16
15
|
|
17
16
|
# Default options to Byebug.start
|
18
|
-
DEFAULT_START_SETTINGS
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
unless defined?(DEFAULT_START_SETTINGS)
|
18
|
+
DEFAULT_START_SETTINGS = { post_mortem: false,
|
19
|
+
tracing: false,
|
20
|
+
save_history: true }
|
21
|
+
end
|
23
22
|
|
24
23
|
# Configuration file used for startup commands. Default value is .byebugrc
|
25
24
|
INITFILE = '.byebugrc' unless defined?(INITFILE)
|
26
25
|
|
26
|
+
# Original ARGV, command line and initial directory to make restarts possible
|
27
|
+
ARGV = ARGV.clone unless defined?(ARGV)
|
28
|
+
PROG_SCRIPT = $0 unless defined?(PROG_SCRIPT)
|
29
|
+
INITIAL_DIR = Dir.pwd unless defined?(INITIAL_DIR)
|
30
|
+
|
27
31
|
class << self
|
28
32
|
|
29
33
|
# processor modules provide +handler+ object
|
30
34
|
attr_accessor :handler
|
31
35
|
Byebug.handler = CommandProcessor.new
|
32
36
|
|
33
|
-
attr_accessor :last_exception
|
34
|
-
Byebug.last_exception = nil
|
35
|
-
|
36
37
|
def source_reload
|
37
38
|
Object.send(:remove_const, 'SCRIPT_LINES__') if
|
38
39
|
Object.const_defined?('SCRIPT_LINES__')
|
@@ -102,25 +103,23 @@ module Byebug
|
|
102
103
|
# many times as you called Byebug.start method.</i>
|
103
104
|
#
|
104
105
|
# +options+ is a hash used to set various debugging options.
|
105
|
-
# :
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
112
|
-
# can't be unset.
|
106
|
+
# :post_mortem - true if you want to enter post-mortem debugging on an
|
107
|
+
# uncaught exception, false otherwise. Default: false.
|
108
|
+
# :tracing - true if line tracing should be enabled, false otherwise.
|
109
|
+
# Default: false.
|
110
|
+
# :save_history - true if byebug's command history should be saved to a
|
111
|
+
# file on program termination so that it can be reloaded
|
112
|
+
# later.
|
113
113
|
#
|
114
114
|
def start(options={}, &block)
|
115
115
|
options = Byebug::DEFAULT_START_SETTINGS.merge(options)
|
116
|
-
|
117
|
-
|
118
|
-
Byebug.const_set('PROG_SCRIPT', $0) unless defined? Byebug::PROG_SCRIPT
|
119
|
-
Byebug.const_set('INITIAL_DIR', Dir.pwd) unless defined? Byebug::INITIAL_DIR
|
120
|
-
end
|
121
|
-
Byebug.tracing = options[:tracing] unless options[:tracing].nil?
|
116
|
+
Byebug.tracing = options[:tracing]
|
117
|
+
|
122
118
|
retval = Byebug._start(&block)
|
119
|
+
|
123
120
|
post_mortem if options[:post_mortem]
|
121
|
+
at_exit { Byebug::History.save } if options[:save_history]
|
122
|
+
|
124
123
|
return retval
|
125
124
|
end
|
126
125
|
|
@@ -139,7 +138,7 @@ module Byebug
|
|
139
138
|
|
140
139
|
home_script = File.expand_path(File.join(ENV['HOME'].to_s, INITFILE))
|
141
140
|
if File.exist?(home_script) and cwd_script != home_script
|
142
|
-
|
141
|
+
run_script(home_script, out)
|
143
142
|
end
|
144
143
|
end
|
145
144
|
|
@@ -161,17 +160,17 @@ module Byebug
|
|
161
160
|
#
|
162
161
|
def post_mortem
|
163
162
|
return if self.post_mortem?
|
164
|
-
at_exit { handle_post_mortem($!) if post_mortem? }
|
165
163
|
self.post_mortem = true
|
164
|
+
at_exit { handle_post_mortem if post_mortem? }
|
166
165
|
end
|
167
166
|
|
168
|
-
def handle_post_mortem
|
169
|
-
|
170
|
-
|
171
|
-
|
167
|
+
def handle_post_mortem
|
168
|
+
context = raised_exception.__bb_context
|
169
|
+
file = raised_exception.__bb_file
|
170
|
+
line = raised_exception.__bb_line
|
172
171
|
orig_tracing = Byebug.tracing?
|
173
172
|
Byebug.tracing = false
|
174
|
-
handler.at_line(
|
173
|
+
handler.at_line(context, file, line)
|
175
174
|
ensure
|
176
175
|
Byebug.tracing = orig_tracing
|
177
176
|
end
|
@@ -185,16 +184,13 @@ end
|
|
185
184
|
|
186
185
|
module Kernel
|
187
186
|
#
|
188
|
-
# Enters byebug after
|
189
|
-
# occur. Before entering byebug
|
187
|
+
# Enters byebug right before (or right after if _before_ is false) return
|
188
|
+
# events occur. Before entering byebug the init script is read.
|
190
189
|
#
|
191
|
-
def byebug(
|
190
|
+
def byebug(steps_out = 1, before = true)
|
192
191
|
Byebug.start
|
193
192
|
Byebug.run_init_script(StringIO.new)
|
194
|
-
|
195
|
-
Byebug.current_context.stop_return steps_out if steps_out >= 1
|
196
|
-
end
|
197
|
-
Byebug.current_context.step_into steps_into if steps_into >= 0
|
193
|
+
Byebug.current_context.step_out(steps_out, before)
|
198
194
|
end
|
199
195
|
|
200
196
|
alias_method :debugger, :byebug
|
data/lib/byebug/command.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'columnize'
|
2
2
|
require 'forwardable'
|
3
|
-
|
3
|
+
require 'byebug/helper'
|
4
4
|
|
5
5
|
module Byebug
|
6
6
|
|
@@ -23,7 +23,7 @@ module Byebug
|
|
23
23
|
@commands ||= []
|
24
24
|
end
|
25
25
|
|
26
|
-
attr_accessor :allow_in_control, :unknown
|
26
|
+
attr_accessor :allow_in_control, :unknown
|
27
27
|
attr_writer :allow_in_post_mortem, :always_run
|
28
28
|
|
29
29
|
def allow_in_post_mortem
|
@@ -143,6 +143,7 @@ module Byebug
|
|
143
143
|
end
|
144
144
|
|
145
145
|
# Register default settings
|
146
|
+
register_setting_var(:autosave, true)
|
146
147
|
register_setting_var(:basename, false)
|
147
148
|
register_setting_var(:callstyle, :long)
|
148
149
|
register_setting_var(:testing, false)
|
@@ -217,6 +218,7 @@ module Byebug
|
|
217
218
|
# :autolist - automatically calls 'list' command on breakpoint
|
218
219
|
# :autoreload - makes 'list' command always display up-to-date source
|
219
220
|
# code
|
221
|
+
# :autosave - automatic saving of command history on exit
|
220
222
|
# :frame_class_names - displays method's class name when showing frame stack
|
221
223
|
# :forcestep - stepping command always move to the new line
|
222
224
|
# :fullpath - displays full paths when showing frame stack
|
data/lib/byebug/commands/edit.rb
CHANGED
@@ -3,21 +3,18 @@ module Byebug
|
|
3
3
|
# Implements byebug's 'finish' command.
|
4
4
|
class FinishCommand < Command
|
5
5
|
self.allow_in_post_mortem = false
|
6
|
-
self.need_context = true
|
7
6
|
|
8
7
|
def regexp
|
9
8
|
/^\s* fin(?:ish)? (?:\s+(\S+))? \s*$/x
|
10
9
|
end
|
11
10
|
|
12
11
|
def execute
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
@state.context.step_out frame_pos
|
12
|
+
max_frames = Context.stack_size - @state.frame_pos
|
13
|
+
n_frames = get_int(@match[1], "finish", 0, max_frames - 1, 1)
|
14
|
+
return nil unless n_frames
|
15
|
+
|
16
|
+
force = n_frames == 0 ? true : false
|
17
|
+
@state.context.step_out(@state.frame_pos + n_frames, force)
|
21
18
|
@state.frame_pos = 0
|
22
19
|
@state.proceed
|
23
20
|
end
|
@@ -28,14 +25,11 @@ module Byebug
|
|
28
25
|
end
|
29
26
|
|
30
27
|
def description
|
31
|
-
%{fin[ish][
|
32
|
-
|
33
|
-
If no frame number is given, we run until the currently selected frame
|
34
|
-
returns. The currently selected frame starts out the most-recent frame
|
35
|
-
or 0 if no frame positioning (e.g "up", "down" or "frame") has been
|
36
|
-
performed.
|
28
|
+
%{fin[ish][ n_frames]\tExecute until frame returns.
|
37
29
|
|
38
|
-
If
|
30
|
+
If no number is given, we run until the current frame returns. If a
|
31
|
+
number of frames `n_frames` is given, then we run until `n_frames`
|
32
|
+
return from the current position.}
|
39
33
|
end
|
40
34
|
end
|
41
35
|
end
|
data/lib/byebug/commands/help.rb
CHANGED
@@ -21,7 +21,7 @@ module Byebug
|
|
21
21
|
help.pop if help.last && help.last.empty?
|
22
22
|
return print help.join("\n") + "\n"
|
23
23
|
else
|
24
|
-
return errmsg "Undefined command: \"#{args[0]}\".
|
24
|
+
return errmsg "Undefined command: \"#{args[0]}\". Try \"help\".\n" if
|
25
25
|
args[0]
|
26
26
|
end
|
27
27
|
end
|
data/lib/byebug/commands/kill.rb
CHANGED
data/lib/byebug/commands/quit.rb
CHANGED
data/lib/byebug/commands/repl.rb
CHANGED
@@ -50,12 +50,12 @@ end
|
|
50
50
|
module Byebug
|
51
51
|
|
52
52
|
# Implements byebug's "irb" command.
|
53
|
-
class
|
53
|
+
class IrbCommand < Command
|
54
54
|
register_setting_get(:autoirb) do
|
55
|
-
|
55
|
+
IrbCommand.always_run
|
56
56
|
end
|
57
57
|
register_setting_set(:autoirb) do |value|
|
58
|
-
|
58
|
+
IrbCommand.always_run = value
|
59
59
|
end
|
60
60
|
|
61
61
|
def regexp
|