byebug 4.0.5 → 5.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/CHANGELOG.md +72 -34
- data/CONTRIBUTING.md +26 -31
- data/README.md +3 -3
- data/lib/byebug/breakpoint.rb +2 -1
- data/lib/byebug/command.rb +27 -49
- data/lib/byebug/commands/break.rb +21 -15
- data/lib/byebug/commands/catch.rb +9 -15
- data/lib/byebug/commands/condition.rb +12 -15
- data/lib/byebug/commands/continue.rb +8 -11
- data/lib/byebug/commands/delete.rb +9 -12
- data/lib/byebug/commands/disable.rb +32 -0
- data/lib/byebug/commands/disable/breakpoints.rb +38 -0
- data/lib/byebug/commands/disable/display.rb +39 -0
- data/lib/byebug/commands/display.rb +18 -51
- data/lib/byebug/commands/down.rb +39 -0
- data/lib/byebug/commands/edit.rb +8 -14
- data/lib/byebug/commands/enable.rb +25 -0
- data/lib/byebug/commands/enable/breakpoints.rb +38 -0
- data/lib/byebug/commands/enable/display.rb +39 -0
- data/lib/byebug/commands/eval.rb +10 -192
- data/lib/byebug/commands/finish.rb +11 -12
- data/lib/byebug/commands/frame.rb +17 -182
- data/lib/byebug/commands/help.rb +18 -18
- data/lib/byebug/commands/history.rb +9 -10
- data/lib/byebug/commands/info.rb +17 -190
- data/lib/byebug/commands/info/args.rb +39 -0
- data/lib/byebug/commands/info/breakpoints.rb +59 -0
- data/lib/byebug/commands/info/catch.rb +39 -0
- data/lib/byebug/commands/info/display.rb +42 -0
- data/lib/byebug/commands/info/file.rb +81 -0
- data/lib/byebug/commands/info/line.rb +31 -0
- data/lib/byebug/commands/info/program.rb +51 -0
- data/lib/byebug/commands/interrupt.rb +5 -9
- data/lib/byebug/commands/irb.rb +5 -9
- data/lib/byebug/commands/kill.rb +6 -12
- data/lib/byebug/commands/list.rb +47 -19
- data/lib/byebug/commands/method.rb +8 -14
- data/lib/byebug/commands/next.rb +36 -0
- data/lib/byebug/commands/pp.rb +41 -0
- data/lib/byebug/commands/pry.rb +5 -9
- data/lib/byebug/commands/ps.rb +44 -0
- data/lib/byebug/commands/putl.rb +43 -0
- data/lib/byebug/commands/quit.rb +8 -12
- data/lib/byebug/commands/restart.rb +6 -12
- data/lib/byebug/commands/save.rb +30 -39
- data/lib/byebug/commands/set.rb +19 -21
- data/lib/byebug/commands/show.rb +10 -16
- data/lib/byebug/commands/source.rb +6 -12
- data/lib/byebug/commands/step.rb +36 -0
- data/lib/byebug/commands/thread.rb +13 -130
- data/lib/byebug/commands/thread/current.rb +35 -0
- data/lib/byebug/commands/thread/list.rb +41 -0
- data/lib/byebug/commands/thread/resume.rb +45 -0
- data/lib/byebug/commands/thread/stop.rb +41 -0
- data/lib/byebug/commands/thread/switch.rb +43 -0
- data/lib/byebug/commands/tracevar.rb +8 -14
- data/lib/byebug/commands/undisplay.rb +12 -15
- data/lib/byebug/commands/untracevar.rb +5 -11
- data/lib/byebug/commands/up.rb +39 -0
- data/lib/byebug/commands/var.rb +15 -94
- data/lib/byebug/commands/var/all.rb +37 -0
- data/lib/byebug/commands/var/const.rb +38 -0
- data/lib/byebug/commands/var/global.rb +33 -0
- data/lib/byebug/commands/var/instance.rb +35 -0
- data/lib/byebug/commands/var/local.rb +35 -0
- data/lib/byebug/commands/where.rb +47 -0
- data/lib/byebug/core.rb +10 -0
- data/lib/byebug/helpers/eval.rb +47 -0
- data/lib/byebug/helpers/file.rb +46 -0
- data/lib/byebug/helpers/frame.rb +76 -0
- data/lib/byebug/helpers/parse.rb +74 -0
- data/lib/byebug/helpers/string.rb +24 -0
- data/lib/byebug/helpers/thread.rb +53 -0
- data/lib/byebug/helpers/toggle.rb +56 -0
- data/lib/byebug/helpers/var.rb +45 -0
- data/lib/byebug/history.rb +2 -4
- data/lib/byebug/interface.rb +5 -3
- data/lib/byebug/interfaces/local_interface.rb +3 -1
- data/lib/byebug/interfaces/remote_interface.rb +3 -1
- data/lib/byebug/interfaces/test_interface.rb +6 -2
- data/lib/byebug/printers/plain.rb +1 -1
- data/lib/byebug/processors/command_processor.rb +9 -11
- data/lib/byebug/processors/control_command_processor.rb +1 -1
- data/lib/byebug/remote.rb +3 -0
- data/lib/byebug/runner.rb +5 -3
- data/lib/byebug/setting.rb +2 -18
- data/lib/byebug/settings/savefile.rb +21 -0
- data/lib/byebug/states/regular_state.rb +15 -6
- data/lib/byebug/subcommand_list.rb +33 -0
- data/lib/byebug/subcommands.rb +53 -0
- data/lib/byebug/version.rb +1 -1
- metadata +45 -6
- data/lib/byebug/commands/enable_disable.rb +0 -132
- data/lib/byebug/commands/stepping.rb +0 -75
- data/lib/byebug/helper.rb +0 -131
data/lib/byebug/commands/help.rb
CHANGED
@@ -8,32 +8,32 @@ module Byebug
|
|
8
8
|
self.allow_in_control = true
|
9
9
|
|
10
10
|
def regexp
|
11
|
-
/^\s* h(?:elp)? (
|
11
|
+
/^\s* h(?:elp)? (?:\s+(\S+))? (?:\s+(\S+))? \s*$/x
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute
|
15
|
-
return puts(
|
15
|
+
return puts(help) unless @match[1]
|
16
16
|
|
17
|
-
cmd =
|
18
|
-
return errmsg(pr('help.errors.undefined', cmd: @match[1])) unless cmd
|
17
|
+
cmd = Byebug.commands.find { |c| c.to_name == @match[1] }
|
18
|
+
return errmsg(pr('help.errors.undefined', cmd: @match[1])) unless cmd
|
19
19
|
|
20
|
-
cmd
|
21
|
-
|
20
|
+
cmd = cmd.new(@state)
|
21
|
+
return puts(cmd.help) unless @match[2]
|
22
|
+
|
23
|
+
subcmd = cmd.subcommands.find(@match[2])
|
24
|
+
return errmsg(pr('help.errors.undefined', cmd: @match[2])) unless subcmd
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
%w(help)
|
26
|
-
end
|
26
|
+
puts(subcmd.help)
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
def description
|
30
|
+
<<-EOD
|
31
|
+
h[elp][ <cmd>[ <subcmd>]]
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
33
|
+
help -- prints this help.
|
34
|
+
help <cmd> -- prints help on command <cmd>.
|
35
|
+
help <cmd> <subcmd> -- prints help on <cmd>'s subcommand <subcmd>.
|
36
|
+
EOD
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'byebug/command'
|
2
|
+
require 'byebug/helpers/parse'
|
2
3
|
|
3
4
|
module Byebug
|
4
5
|
#
|
5
6
|
# Show history of byebug commands.
|
6
7
|
#
|
7
8
|
class HistoryCommand < Command
|
9
|
+
include Helpers::ParseHelper
|
10
|
+
|
8
11
|
def regexp
|
9
12
|
/^\s* hist(?:ory)? (?:\s+(?<num_cmds>.+))? \s*$/x
|
10
13
|
end
|
@@ -13,23 +16,19 @@ module Byebug
|
|
13
16
|
history = @state.interface.history
|
14
17
|
|
15
18
|
if @match[:num_cmds]
|
16
|
-
size,
|
19
|
+
size, = get_int(@match[:num_cmds], 'history', 1, history.size)
|
17
20
|
return errmsg(err) unless size
|
18
21
|
end
|
19
22
|
|
20
23
|
puts history.to_s(size)
|
21
24
|
end
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
26
|
+
def description
|
27
|
+
<<-EOD
|
28
|
+
hist[ory] [num_cmds]
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
hist[ory] [num_cmds] Show byebug's command history.
|
31
|
-
EOD
|
32
|
-
end
|
30
|
+
Show byebug's command history.
|
31
|
+
EOD
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
data/lib/byebug/commands/info.rb
CHANGED
@@ -1,205 +1,32 @@
|
|
1
|
-
require 'byebug/
|
1
|
+
require 'byebug/subcommands'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
if Byebug.catchpoints && !Byebug.catchpoints.empty?
|
12
|
-
Byebug.catchpoints.each do |exception, _hits|
|
13
|
-
puts("#{exception}: #{exception.is_a?(Class)}")
|
14
|
-
end
|
15
|
-
else
|
16
|
-
puts 'No exceptions set to be caught.'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def info_args(*args)
|
21
|
-
locals = @state.context.frame_locals
|
22
|
-
args = @state.context.frame_args
|
23
|
-
return if args == [[:rest]]
|
24
|
-
|
25
|
-
args.map do |_, name|
|
26
|
-
s = "#{name} = #{locals[name].inspect}"
|
27
|
-
s[Setting[:width] - 3..-1] = '...' if s.size > Setting[:width]
|
28
|
-
puts s
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def info_breakpoint(brkpt)
|
33
|
-
expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}"
|
34
|
-
y_n = brkpt.enabled? ? 'y' : 'n'
|
35
|
-
interp = format('%-3d %-3s at %s:%s%s',
|
36
|
-
brkpt.id, y_n, brkpt.source, brkpt.pos, expr)
|
37
|
-
puts interp
|
38
|
-
hits = brkpt.hit_count
|
39
|
-
return unless hits > 0
|
40
|
-
|
41
|
-
s = (hits > 1) ? 's' : ''
|
42
|
-
puts "\tbreakpoint already hit #{hits} time#{s}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def info_breakpoints(*args)
|
46
|
-
return puts('No breakpoints.') if Byebug.breakpoints.empty?
|
47
|
-
|
48
|
-
brkpts = Byebug.breakpoints.sort_by(&:id)
|
49
|
-
unless args.empty?
|
50
|
-
indices = args.map(&:to_i)
|
51
|
-
brkpts = brkpts.select { |b| indices.member?(b.id) }
|
52
|
-
return errmsg('No breakpoints found among list given') if brkpts.empty?
|
53
|
-
end
|
54
|
-
|
55
|
-
puts 'Num Enb What'
|
56
|
-
brkpts.each { |b| info_breakpoint(b) }
|
57
|
-
end
|
58
|
-
|
59
|
-
def info_display(*_args)
|
60
|
-
return puts('There are no auto-display expressions now.') unless
|
61
|
-
@state.display.find { |d| d[0] }
|
62
|
-
|
63
|
-
puts 'Auto-display expressions now in effect:'
|
64
|
-
puts 'Num Enb Expression'
|
65
|
-
n = 1
|
66
|
-
@state.display.each do |d|
|
67
|
-
puts(format('%3d: %s %s', n, d[0] ? 'y' : 'n', d[1]))
|
68
|
-
n += 1
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
include FileFunctions
|
73
|
-
|
74
|
-
def info_file_basic(file)
|
75
|
-
path = File.expand_path(file)
|
76
|
-
return unless File.exist?(path)
|
77
|
-
|
78
|
-
s = n_lines(path) == 1 ? '' : 's'
|
79
|
-
"#{path} (#{n_lines(path)} line#{s})"
|
80
|
-
end
|
81
|
-
|
82
|
-
def info_file_breakpoints(file)
|
83
|
-
breakpoints = Breakpoint.potential_lines(file)
|
84
|
-
return unless breakpoints
|
85
|
-
|
86
|
-
breakpoints.to_a.sort.columnize(line_prefix: ' ',
|
87
|
-
displaywidth: Setting[:width])
|
88
|
-
end
|
89
|
-
|
90
|
-
def info_file_mtime(file)
|
91
|
-
File.stat(file).mtime
|
92
|
-
end
|
93
|
-
|
94
|
-
def info_file_sha1(file)
|
95
|
-
require 'digest/sha1'
|
96
|
-
Digest::SHA1.hexdigest(file)
|
97
|
-
end
|
98
|
-
|
99
|
-
def info_line(*_args)
|
100
|
-
puts "Line #{@state.line} of \"#{@state.file}\""
|
101
|
-
end
|
102
|
-
|
103
|
-
def info_stop_reason(stop_reason)
|
104
|
-
case stop_reason
|
105
|
-
when :step
|
106
|
-
puts "It stopped after stepping, next'ing or initial start."
|
107
|
-
when :breakpoint
|
108
|
-
puts 'It stopped at a breakpoint.'
|
109
|
-
when :catchpoint
|
110
|
-
puts 'It stopped at a catchpoint.'
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def info_program(*_args)
|
115
|
-
if @state.context.dead?
|
116
|
-
puts 'The program crashed.'
|
117
|
-
excpt = Byebug.last_exception
|
118
|
-
return puts("Exception: #{excpt.inspect}") if excpt
|
119
|
-
end
|
120
|
-
|
121
|
-
puts 'Program stopped. '
|
122
|
-
info_stop_reason @state.context.stop_reason
|
123
|
-
end
|
124
|
-
end
|
3
|
+
require 'byebug/commands/info/args'
|
4
|
+
require 'byebug/commands/info/breakpoints'
|
5
|
+
require 'byebug/commands/info/catch'
|
6
|
+
require 'byebug/commands/info/display'
|
7
|
+
require 'byebug/commands/info/file'
|
8
|
+
require 'byebug/commands/info/line'
|
9
|
+
require 'byebug/commands/info/program'
|
125
10
|
|
11
|
+
module Byebug
|
126
12
|
#
|
127
|
-
#
|
13
|
+
# Shows info about different aspects of the debugger.
|
128
14
|
#
|
129
15
|
class InfoCommand < Command
|
130
|
-
include
|
131
|
-
include InfoFunctions
|
16
|
+
include Subcommands
|
132
17
|
|
133
18
|
self.allow_in_control = true
|
134
19
|
|
135
|
-
Subcommands = [
|
136
|
-
['args', 1, 'Argument variables of current stack frame'],
|
137
|
-
['breakpoints', 1, 'Status of user-settable breakpoints',
|
138
|
-
'Without argument, list info about all breakpoints. With an integer ' \
|
139
|
-
'argument, list info on that breakpoint.'],
|
140
|
-
['catch', 3, 'Exceptions that can be caught in the current stack frame'],
|
141
|
-
['display', 2, 'Expressions to display when program stops'],
|
142
|
-
['file', 4, 'Info about a particular file read in',
|
143
|
-
'File name, number of lines, possible breakpoints in the file, last ' \
|
144
|
-
'modification time and sha1 digest are listed.'],
|
145
|
-
['line', 2, 'Line number and file name of current position in source ' \
|
146
|
-
'file.'],
|
147
|
-
['program', 2, 'Execution status of the program']
|
148
|
-
].map do |name, min, help|
|
149
|
-
Subcmd.new(name, min, help)
|
150
|
-
end
|
151
|
-
|
152
|
-
def info_file(*args)
|
153
|
-
file = args[0] || @state.file
|
154
|
-
unless File.exist?(file)
|
155
|
-
return errmsg(pr('info.errors.undefined_file', file: file))
|
156
|
-
end
|
157
|
-
|
158
|
-
puts <<-EOC.gsub(/^ {6}/, '')
|
159
|
-
|
160
|
-
File #{info_file_basic(file)}
|
161
|
-
|
162
|
-
Breakpoint line numbers:
|
163
|
-
#{info_file_breakpoints(file)}
|
164
|
-
|
165
|
-
Modification time: #{info_file_mtime(file)}
|
166
|
-
|
167
|
-
Sha1 Signature: #{info_file_sha1(file)}
|
168
|
-
|
169
|
-
EOC
|
170
|
-
end
|
171
|
-
|
172
20
|
def regexp
|
173
|
-
/^\s* i(?:nfo)? (?:\s+(.+))? \s*$/x
|
174
|
-
end
|
175
|
-
|
176
|
-
def execute
|
177
|
-
return puts(self.class.help) unless @match[1]
|
178
|
-
|
179
|
-
args = @match[1].split(/ +/)
|
180
|
-
param = args.shift
|
181
|
-
subcmd = Command.find(Subcommands, param)
|
182
|
-
return errmsg "Unknown info command #{param}\n" unless subcmd
|
183
|
-
|
184
|
-
if @state.context
|
185
|
-
send("info_#{subcmd.name}", *args)
|
186
|
-
else
|
187
|
-
errmsg "'info #{subcmd.name}' not available without a context.\n"
|
188
|
-
end
|
21
|
+
/^\s* i(?:nfo)? (?:\s+ (.+))? \s*$/x
|
189
22
|
end
|
190
23
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
end
|
195
|
-
|
196
|
-
def description
|
197
|
-
prettify <<-EOD
|
198
|
-
info[ subcommand]
|
24
|
+
def description
|
25
|
+
<<-EOD
|
26
|
+
info[ subcommand]
|
199
27
|
|
200
|
-
|
201
|
-
|
202
|
-
end
|
28
|
+
Generic command for showing things about the program being debugged.
|
29
|
+
EOD
|
203
30
|
end
|
204
31
|
end
|
205
32
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Byebug
|
2
|
+
#
|
3
|
+
# Reopens the +info+ command to define the +args+ subcommand
|
4
|
+
#
|
5
|
+
class InfoCommand < Command
|
6
|
+
#
|
7
|
+
# Information about arguments of the current method/block
|
8
|
+
#
|
9
|
+
class ArgsSubcommand < Command
|
10
|
+
def regexp
|
11
|
+
/^\s* a(?:rgs)? \s*$/x
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
locals = @state.context.frame_locals
|
16
|
+
args = @state.context.frame_args
|
17
|
+
return if args == [[:rest]]
|
18
|
+
|
19
|
+
args.map do |_, name|
|
20
|
+
s = "#{name} = #{locals[name].inspect}"
|
21
|
+
s[Setting[:width] - 3..-1] = '...' if s.size > Setting[:width]
|
22
|
+
puts s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def short_description
|
27
|
+
'Information about arguments of the current method/block'
|
28
|
+
end
|
29
|
+
|
30
|
+
def description
|
31
|
+
<<-EOD
|
32
|
+
inf[o] a[args]
|
33
|
+
|
34
|
+
#{short_description}
|
35
|
+
EOD
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Byebug
|
2
|
+
#
|
3
|
+
# Reopens the +info+ command to define the +breakpoints+ subcommand
|
4
|
+
#
|
5
|
+
class InfoCommand < Command
|
6
|
+
#
|
7
|
+
# Information about current breakpoints
|
8
|
+
#
|
9
|
+
class BreakpointsSubcommand < Command
|
10
|
+
def regexp
|
11
|
+
/^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
return puts('No breakpoints.') if Byebug.breakpoints.empty?
|
16
|
+
|
17
|
+
breakpoints = Byebug.breakpoints.sort_by(&:id)
|
18
|
+
|
19
|
+
if @match[1]
|
20
|
+
indices = @match[1].split(/ +/).map(&:to_i)
|
21
|
+
breakpoints = breakpoints.select { |b| indices.member?(b.id) }
|
22
|
+
if breakpoints.empty?
|
23
|
+
return errmsg('No breakpoints found among list given')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
puts 'Num Enb What'
|
28
|
+
breakpoints.each { |b| info_breakpoint(b) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def short_description
|
32
|
+
'Status of user settable breakpoints.'
|
33
|
+
end
|
34
|
+
|
35
|
+
def description
|
36
|
+
<<-EOD
|
37
|
+
inf[o] b[reakpoints]
|
38
|
+
|
39
|
+
#{short_description}
|
40
|
+
EOD
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def info_breakpoint(brkpt)
|
46
|
+
expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}"
|
47
|
+
y_n = brkpt.enabled? ? 'y' : 'n'
|
48
|
+
interp = format('%-3d %-3s at %s:%s%s',
|
49
|
+
brkpt.id, y_n, brkpt.source, brkpt.pos, expr)
|
50
|
+
puts interp
|
51
|
+
hits = brkpt.hit_count
|
52
|
+
return unless hits > 0
|
53
|
+
|
54
|
+
s = (hits > 1) ? 's' : ''
|
55
|
+
puts "\tbreakpoint already hit #{hits} time#{s}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Byebug
|
2
|
+
#
|
3
|
+
# Reopens the +info+ command to define the +catch+ subcommand
|
4
|
+
#
|
5
|
+
class InfoCommand < Command
|
6
|
+
#
|
7
|
+
# Information on exceptions that can be caught by the debugger
|
8
|
+
#
|
9
|
+
class CatchSubcommand < Command
|
10
|
+
def regexp
|
11
|
+
/^\s* c(?:atch)? (?:\s+ (.+))? \s*$/x
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
return puts('No frame selected.') unless @state.context
|
16
|
+
|
17
|
+
if Byebug.catchpoints && !Byebug.catchpoints.empty?
|
18
|
+
Byebug.catchpoints.each do |exception, _hits|
|
19
|
+
puts("#{exception}: #{exception.is_a?(Class)}")
|
20
|
+
end
|
21
|
+
else
|
22
|
+
puts 'No exceptions set to be caught.'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def short_description
|
27
|
+
'Exceptions that can be caught in the current stack frame'
|
28
|
+
end
|
29
|
+
|
30
|
+
def description
|
31
|
+
<<-EOD
|
32
|
+
inf[o] c[atch]
|
33
|
+
|
34
|
+
#{short_description}
|
35
|
+
EOD
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|