byebug 3.1.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/CHANGELOG.md +15 -0
- data/GUIDE.md +17 -35
- data/Gemfile +8 -5
- data/LICENSE +1 -1
- data/README.md +10 -22
- data/Rakefile +1 -1
- data/ext/byebug/byebug.c +3 -2
- data/lib/byebug.rb +3 -38
- data/lib/byebug/commands/break.rb +83 -0
- data/lib/byebug/commands/catchpoint.rb +0 -1
- data/lib/byebug/commands/condition.rb +10 -6
- data/lib/byebug/commands/continue.rb +3 -6
- data/lib/byebug/commands/delete.rb +38 -0
- data/lib/byebug/commands/edit.rb +0 -2
- data/lib/byebug/commands/enable.rb +7 -8
- data/lib/byebug/commands/finish.rb +0 -2
- data/lib/byebug/commands/frame.rb +13 -15
- data/lib/byebug/commands/help.rb +1 -3
- data/lib/byebug/commands/history.rb +3 -3
- data/lib/byebug/commands/info.rb +4 -13
- data/lib/byebug/commands/interrupt.rb +25 -0
- data/lib/byebug/commands/kill.rb +0 -2
- data/lib/byebug/commands/list.rb +2 -4
- data/lib/byebug/commands/method.rb +2 -8
- data/lib/byebug/commands/quit.rb +0 -2
- data/lib/byebug/commands/reload.rb +2 -15
- data/lib/byebug/commands/repl.rb +0 -3
- data/lib/byebug/commands/{control.rb → restart.rb} +2 -26
- data/lib/byebug/commands/save.rb +0 -1
- data/lib/byebug/commands/set.rb +4 -7
- data/lib/byebug/commands/show.rb +0 -3
- data/lib/byebug/commands/source.rb +0 -3
- data/lib/byebug/commands/stepping.rb +3 -4
- data/lib/byebug/commands/trace.rb +0 -1
- data/lib/byebug/commands/variables.rb +3 -4
- data/lib/byebug/context.rb +0 -1
- data/lib/byebug/helper.rb +23 -0
- data/lib/byebug/interfaces/script_interface.rb +1 -1
- data/lib/byebug/processors/command_processor.rb +9 -9
- data/lib/byebug/remote.rb +2 -2
- data/lib/byebug/setting.rb +3 -1
- data/lib/byebug/settings/autoeval.rb +3 -1
- data/lib/byebug/settings/autoirb.rb +3 -1
- data/lib/byebug/settings/autolist.rb +3 -1
- data/lib/byebug/settings/autoreload.rb +1 -3
- data/lib/byebug/settings/autosave.rb +1 -3
- data/lib/byebug/settings/callstyle.rb +2 -4
- data/lib/byebug/settings/fullpath.rb +1 -3
- data/lib/byebug/settings/histfile.rb +1 -3
- data/lib/byebug/settings/histsize.rb +0 -4
- data/lib/byebug/settings/listsize.rb +1 -3
- data/lib/byebug/settings/post_mortem.rb +14 -1
- data/lib/byebug/settings/width.rb +1 -17
- data/lib/byebug/version.rb +1 -1
- data/test/break_test.rb +376 -0
- data/test/condition_test.rb +82 -0
- data/test/continue_test.rb +27 -30
- data/test/debugger_alias_test.rb +4 -4
- data/test/delete_test.rb +26 -0
- data/test/display_test.rb +80 -102
- data/test/edit_test.rb +28 -31
- data/test/eval_test.rb +50 -80
- data/test/finish_test.rb +23 -23
- data/test/frame_test.rb +172 -186
- data/test/help_test.rb +27 -37
- data/test/history_test.rb +32 -41
- data/test/info_test.rb +198 -230
- data/test/interrupt_test.rb +17 -36
- data/test/irb_test.rb +47 -0
- data/test/kill_test.rb +19 -19
- data/test/list_test.rb +126 -133
- data/test/method_test.rb +21 -54
- data/test/post_mortem_test.rb +44 -46
- data/test/pry_test.rb +42 -0
- data/test/quit_test.rb +17 -15
- data/test/reload_test.rb +23 -28
- data/test/restart_test.rb +35 -63
- data/test/save_test.rb +46 -62
- data/test/set_test.rb +93 -144
- data/test/show_test.rb +50 -71
- data/test/source_test.rb +23 -26
- data/test/stepping_test.rb +125 -153
- data/test/support/matchers.rb +1 -6
- data/test/support/test_interface.rb +1 -1
- data/test/support/{test_dsl.rb → utils.rb} +17 -64
- data/test/test_helper.rb +25 -7
- data/test/thread_test.rb +101 -89
- data/test/trace_test.rb +48 -85
- data/test/variables_test.rb +43 -80
- metadata +18 -13
- data/lib/byebug/commands/breakpoints.rb +0 -137
- data/lib/byebug/commands/skip.rb +0 -30
- data/test/breakpoints_test.rb +0 -474
- data/test/conditions_test.rb +0 -82
- data/test/repl_test.rb +0 -75
@@ -1,6 +1,4 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
|
-
# Implements byebug "continue" command.
|
4
2
|
class ContinueCommand < Command
|
5
3
|
self.allow_in_post_mortem = true
|
6
4
|
|
@@ -12,10 +10,9 @@ module Byebug
|
|
12
10
|
if @match[1] && !@state.context.dead?
|
13
11
|
filename = File.expand_path(@state.file)
|
14
12
|
return unless line_number = get_int(@match[1], "Continue", 0, nil, 0)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
unless LineCache.trace_line_numbers(filename).member?(line_number)
|
14
|
+
return errmsg "Line #{line_number} is not a valid stopping point in file\n"
|
15
|
+
end
|
19
16
|
Byebug.add_breakpoint filename, line_number
|
20
17
|
end
|
21
18
|
@state.proceed
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Byebug
|
2
|
+
class DeleteCommand < Command
|
3
|
+
self.allow_in_post_mortem = false
|
4
|
+
self.allow_in_control = true
|
5
|
+
|
6
|
+
def regexp
|
7
|
+
/^\s* del(?:ete)? (?:\s+(.*))?$/x
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
return errmsg "We are not in a state we can delete breakpoints.\n" unless
|
12
|
+
@state.context
|
13
|
+
|
14
|
+
if not @match[1]
|
15
|
+
Byebug.breakpoints.clear if confirm("Delete all breakpoints? (y or n) ")
|
16
|
+
else
|
17
|
+
@match[1].split(/[ \t]+/).each do |pos|
|
18
|
+
return unless pos = get_int(pos, "Delete", 1)
|
19
|
+
errmsg "No breakpoint number %d\n", pos unless
|
20
|
+
Byebug.remove_breakpoint(pos)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def names
|
27
|
+
%w(delete)
|
28
|
+
end
|
29
|
+
|
30
|
+
def description
|
31
|
+
%{del[ete][ nnn...]
|
32
|
+
|
33
|
+
Without and argument, deletes all breakpoints. With integer arguments,
|
34
|
+
it deletes specific breakpoints.}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/byebug/commands/edit.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
|
-
#
|
2
|
+
#
|
3
|
+
# Mixin to assist command parsing
|
4
|
+
#
|
4
5
|
module EnableDisableFunctions
|
5
6
|
def enable_disable_breakpoints(is_enable, args)
|
6
|
-
return errmsg "No breakpoints have been set
|
7
|
+
return errmsg "No breakpoints have been set" if Byebug.breakpoints.empty?
|
7
8
|
|
8
9
|
all_breakpoints = Byebug.breakpoints.sort_by {|b| b.id }
|
9
10
|
if args.empty?
|
@@ -32,8 +33,7 @@ module Byebug
|
|
32
33
|
|
33
34
|
def enable_disable_display(is_enable, args)
|
34
35
|
if 0 == @state.display.size
|
35
|
-
errmsg "No display expressions have been set
|
36
|
-
return
|
36
|
+
return errmsg "No display expressions have been set\n"
|
37
37
|
end
|
38
38
|
args.each do |pos|
|
39
39
|
pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
|
@@ -64,7 +64,7 @@ module Byebug
|
|
64
64
|
|
65
65
|
def execute
|
66
66
|
return errmsg "\"enable\" must be followed by \"display\", " \
|
67
|
-
"\"breakpoints\" or breakpoint
|
67
|
+
"\"breakpoints\" or breakpoint ids\n" unless @match[1]
|
68
68
|
|
69
69
|
args = @match[1].split(/[ \t]+/)
|
70
70
|
param = args.shift
|
@@ -118,7 +118,7 @@ module Byebug
|
|
118
118
|
|
119
119
|
def execute
|
120
120
|
return errmsg "\"disable\" must be followed by \"display\", " \
|
121
|
-
"\"breakpoints\" or breakpoint
|
121
|
+
"\"breakpoints\" or breakpoint ids\n" unless @match[1]
|
122
122
|
|
123
123
|
args = @match[1].split(/[ \t]+/)
|
124
124
|
param = args.shift
|
@@ -151,5 +151,4 @@ module Byebug
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
end
|
154
|
-
|
155
154
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Byebug
|
3
|
-
|
4
|
-
#
|
3
|
+
#
|
4
|
+
# Mixin to assist command parsing
|
5
|
+
#
|
5
6
|
module FrameFunctions
|
6
7
|
def c_frame?(frame_no)
|
7
8
|
@state.context.frame_binding(frame_no).nil?
|
@@ -52,7 +53,7 @@ module Byebug
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def get_frame_class(style, pos)
|
55
|
-
frame_class = style ==
|
56
|
+
frame_class = style == 'short' ? '' : "#{@state.context.frame_class pos}"
|
56
57
|
return frame_class == '' ? '' : "#{frame_class}."
|
57
58
|
end
|
58
59
|
|
@@ -67,7 +68,7 @@ module Byebug
|
|
67
68
|
args = @state.context.frame_args pos
|
68
69
|
return '' if args.empty?
|
69
70
|
|
70
|
-
locals = @state.context.frame_locals pos if style ==
|
71
|
+
locals = @state.context.frame_locals pos if style == 'long'
|
71
72
|
my_args = args.map do |arg|
|
72
73
|
case arg[0]
|
73
74
|
when :block
|
@@ -77,7 +78,7 @@ module Byebug
|
|
77
78
|
else
|
78
79
|
prefix, default = '', nil
|
79
80
|
end
|
80
|
-
klass = style ==
|
81
|
+
klass = style == 'long' && arg[1] ? "##{locals[arg[1]].class}" : ''
|
81
82
|
"#{prefix}#{arg[1] || default}#{klass}"
|
82
83
|
end
|
83
84
|
|
@@ -118,18 +119,16 @@ module Byebug
|
|
118
119
|
end
|
119
120
|
end
|
120
121
|
|
122
|
+
def shortpath(fullpath)
|
123
|
+
separator = File::ALT_SEPARATOR || File::SEPARATOR
|
124
|
+
"...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
|
125
|
+
end
|
126
|
+
|
121
127
|
def print_frame(pos, mark_current = true)
|
122
|
-
|
128
|
+
fullpath = @state.context.frame_file pos
|
129
|
+
file = Setting[:fullpath] ? fullpath : shortpath(fullpath)
|
123
130
|
line = @state.context.frame_line pos
|
124
131
|
|
125
|
-
unless Setting[:fullpath]
|
126
|
-
path_components = file.split(/[\\\/]/)
|
127
|
-
if path_components.size > 3
|
128
|
-
path_components[0...-3] = '...'
|
129
|
-
file = path_components.join(File::ALT_SEPARATOR || File::SEPARATOR)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
132
|
if mark_current
|
134
133
|
frame_str = (pos == @state.frame_pos) ? '--> ' : ' '
|
135
134
|
else
|
@@ -150,7 +149,6 @@ module Byebug
|
|
150
149
|
end
|
151
150
|
end
|
152
151
|
|
153
|
-
# Implements byebug "where" or "backtrace" command.
|
154
152
|
class WhereCommand < Command
|
155
153
|
def regexp
|
156
154
|
/^\s* (?:w(?:here)?|bt|backtrace) \s*$/x
|
data/lib/byebug/commands/help.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
|
-
# Implements byebug "help" command.
|
4
2
|
class HelpCommand < Command
|
5
3
|
include Columnize
|
6
4
|
|
@@ -26,7 +24,7 @@ module Byebug
|
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
print "byebug help v#{
|
27
|
+
print "byebug help v#{VERSION}\n" unless Setting[:testing]
|
30
28
|
|
31
29
|
print "Type \"help <command-name>\" for help on a specific command\n\n"
|
32
30
|
print "Available commands:\n"
|
@@ -5,11 +5,11 @@ module Byebug
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def execute
|
8
|
-
if
|
8
|
+
if Setting[:autosave]
|
9
9
|
if arg = @match[:num_cmds]
|
10
|
-
size = get_int(arg, 'history', 1,
|
10
|
+
size = get_int(arg, 'history', 1, Setting[:histsize])
|
11
11
|
end
|
12
|
-
print
|
12
|
+
print History.to_s(size || Setting[:histsize])
|
13
13
|
else
|
14
14
|
errmsg "Not currently saving history. Enable it with \"set autosave\"\n"
|
15
15
|
end
|
data/lib/byebug/commands/info.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
2
|
module InfoFunctions
|
4
3
|
def info_catch(*args)
|
5
4
|
return print "No frame selected.\n" unless @state.context
|
@@ -14,7 +13,6 @@ module Byebug
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
# Implements byebug "info" command.
|
18
16
|
class InfoCommand < Command
|
19
17
|
include Columnize
|
20
18
|
self.allow_in_control = true
|
@@ -41,7 +39,6 @@ module Byebug
|
|
41
39
|
'position in source file' ],
|
42
40
|
['locals' , 2, 'Local variables of the current stack frame' ],
|
43
41
|
['program' , 2, 'Execution status of the program' ],
|
44
|
-
['stack' , 2, 'Backtrace of the stack' ],
|
45
42
|
['variables' , 1, 'Local and instance variables of the ' \
|
46
43
|
'current stack frame' ]
|
47
44
|
].map do |name, min, help|
|
@@ -141,8 +138,8 @@ module Byebug
|
|
141
138
|
private :info_file_path
|
142
139
|
|
143
140
|
def info_file_lines(file)
|
144
|
-
lines =
|
145
|
-
print "\t
|
141
|
+
lines = File.foreach(file)
|
142
|
+
print "\t#{lines.count} lines\n" if lines
|
146
143
|
end
|
147
144
|
private :info_file_lines
|
148
145
|
|
@@ -156,13 +153,13 @@ module Byebug
|
|
156
153
|
private :info_file_breakpoints
|
157
154
|
|
158
155
|
def info_file_mtime(file)
|
159
|
-
stat =
|
156
|
+
stat = File.stat(file)
|
160
157
|
print "\t#{stat.mtime}\n" if stat
|
161
158
|
end
|
162
159
|
private :info_file_mtime
|
163
160
|
|
164
161
|
def info_file_sha1(file)
|
165
|
-
print "\t#{
|
162
|
+
print "\t#{Digest::SHA1.hexdigest(file)}\n"
|
166
163
|
end
|
167
164
|
private :info_file_sha1
|
168
165
|
|
@@ -250,10 +247,6 @@ module Byebug
|
|
250
247
|
info_stop_reason @state.context.stop_reason
|
251
248
|
end
|
252
249
|
|
253
|
-
def info_stack(*args)
|
254
|
-
print_backtrace
|
255
|
-
end
|
256
|
-
|
257
250
|
def info_global_variables(*args)
|
258
251
|
var_global
|
259
252
|
end
|
@@ -295,7 +288,5 @@ module Byebug
|
|
295
288
|
return str
|
296
289
|
end
|
297
290
|
end
|
298
|
-
|
299
291
|
end
|
300
|
-
|
301
292
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Byebug
|
2
|
+
class InterruptCommand < Command
|
3
|
+
self.allow_in_control = true
|
4
|
+
self.allow_in_post_mortem = false
|
5
|
+
|
6
|
+
def regexp
|
7
|
+
/^\s*i(?:nterrupt)?\s*$/
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
context = Byebug.thread_context(Thread.main)
|
12
|
+
context.interrupt
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def names
|
17
|
+
%w(interrupt)
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
%{i|nterrupt\t interrupt the program}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/byebug/commands/kill.rb
CHANGED
data/lib/byebug/commands/list.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
|
-
# Implements byebug "list" command.
|
4
2
|
class ListCommand < Command
|
5
3
|
def regexp
|
6
4
|
/^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/x
|
@@ -8,8 +6,8 @@ module Byebug
|
|
8
6
|
|
9
7
|
def execute
|
10
8
|
Byebug.source_reload if Setting[:autoreload]
|
11
|
-
|
12
|
-
|
9
|
+
|
10
|
+
unless lines = get_lines(@state.file)
|
13
11
|
errmsg "No sourcefile available for #{@state.file}\n"
|
14
12
|
return @state.previous_line
|
15
13
|
end
|
@@ -1,19 +1,14 @@
|
|
1
1
|
module Byebug
|
2
|
-
# Implements byebug's 'method' command.
|
3
2
|
class MethodCommand < Command
|
4
3
|
include Columnize
|
5
4
|
|
6
5
|
def regexp
|
7
|
-
/^\s* m(?:ethod)? \s+ (
|
6
|
+
/^\s* m(?:ethod)? \s+ (i(:?nstance)?\s+)?/x
|
8
7
|
end
|
9
8
|
|
10
9
|
def execute
|
11
10
|
obj = bb_eval(@match.post_match)
|
12
|
-
if @match[1]
|
13
|
-
obj.instance_variables.sort.each do |v|
|
14
|
-
print "#{v} = #{obj.instance_variable_get(v).inspect}\n"
|
15
|
-
end
|
16
|
-
elsif @match[1]
|
11
|
+
if @match[1]
|
17
12
|
print "#{columnize(obj.methods.sort(), Setting[:width])}\n"
|
18
13
|
elsif !obj.kind_of?(Module)
|
19
14
|
print "Should be Class/Module: #{@match.post_match}\n"
|
@@ -29,7 +24,6 @@ module Byebug
|
|
29
24
|
|
30
25
|
def description
|
31
26
|
%{m[ethod] i[nstance] <obj>\tshow methods of object
|
32
|
-
m[ethod] iv <obj>\t\tshow instance variables of object
|
33
27
|
m[ethod] <class|module>\t\tshow instance methods of class or module}
|
34
28
|
end
|
35
29
|
end
|
data/lib/byebug/commands/quit.rb
CHANGED
@@ -1,17 +1,4 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
|
-
module ReloadFunctions
|
4
|
-
def getlines(file, line)
|
5
|
-
unless (lines = SCRIPT_LINES__[file]) and lines != true
|
6
|
-
Tracer::Single.get_line(file, line) if File.exist?(file)
|
7
|
-
lines = SCRIPT_LINES__[file]
|
8
|
-
lines = nil if lines == true
|
9
|
-
end
|
10
|
-
lines
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Implements byebug "reload" command.
|
15
2
|
class ReloadCommand < Command
|
16
3
|
self.allow_in_control = true
|
17
4
|
self.allow_in_post_mortem = false
|
@@ -22,8 +9,8 @@ module Byebug
|
|
22
9
|
|
23
10
|
def execute
|
24
11
|
Byebug.source_reload
|
25
|
-
|
26
|
-
|
12
|
+
onoff = Setting[:autoreload] ? 'on' : 'off'
|
13
|
+
print "Source code was reloaded. Automatic reloading is #{onoff}\n"
|
27
14
|
end
|
28
15
|
|
29
16
|
class << self
|
data/lib/byebug/commands/repl.rb
CHANGED
@@ -48,8 +48,6 @@ module IRB
|
|
48
48
|
end
|
49
49
|
|
50
50
|
module Byebug
|
51
|
-
|
52
|
-
# Implements byebug's "irb" command.
|
53
51
|
class IrbCommand < Command
|
54
52
|
def regexp
|
55
53
|
/^\s* irb \s*$/x
|
@@ -101,7 +99,6 @@ module Byebug
|
|
101
99
|
has_pry = false
|
102
100
|
end
|
103
101
|
|
104
|
-
# Implements byebug's "pry" command
|
105
102
|
class PryCommand < Command
|
106
103
|
def regexp
|
107
104
|
/^\s* pry \s*$/x
|
@@ -7,8 +7,8 @@ module Byebug
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def execute
|
10
|
-
prog =
|
11
|
-
byebug_script =
|
10
|
+
prog = PROG_SCRIPT if defined?(PROG_SCRIPT)
|
11
|
+
byebug_script = BYEBUG_SCRIPT if defined?(BYEBUG_SCRIPT)
|
12
12
|
|
13
13
|
return errmsg "Don't know name of debugged program\n" unless prog
|
14
14
|
|
@@ -55,28 +55,4 @@ module Byebug
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
59
|
-
class InterruptCommand < Command
|
60
|
-
self.allow_in_control = true
|
61
|
-
self.allow_in_post_mortem = false
|
62
|
-
|
63
|
-
def regexp
|
64
|
-
/^\s*i(?:nterrupt)?\s*$/
|
65
|
-
end
|
66
|
-
|
67
|
-
def execute
|
68
|
-
context = Byebug.thread_context(Thread.main)
|
69
|
-
context.interrupt
|
70
|
-
end
|
71
|
-
|
72
|
-
class << self
|
73
|
-
def names
|
74
|
-
%w(interrupt)
|
75
|
-
end
|
76
|
-
|
77
|
-
def description
|
78
|
-
%{i|nterrupt\t interrupt the program}
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
58
|
end
|