byebug 4.0.5 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|