runger_byebug 11.2.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 +7 -0
- data/CHANGELOG.md +954 -0
- data/CONTRIBUTING.md +58 -0
- data/GUIDE.md +1806 -0
- data/LICENSE +23 -0
- data/README.md +199 -0
- data/exe/byebug +6 -0
- data/ext/byebug/breakpoint.c +521 -0
- data/ext/byebug/byebug.c +900 -0
- data/ext/byebug/byebug.h +145 -0
- data/ext/byebug/context.c +687 -0
- data/ext/byebug/extconf.rb +12 -0
- data/ext/byebug/locker.c +96 -0
- data/ext/byebug/threads.c +241 -0
- data/lib/byebug/attacher.rb +48 -0
- data/lib/byebug/breakpoint.rb +94 -0
- data/lib/byebug/command.rb +111 -0
- data/lib/byebug/command_list.rb +34 -0
- data/lib/byebug/commands/break.rb +114 -0
- data/lib/byebug/commands/catch.rb +78 -0
- data/lib/byebug/commands/condition.rb +55 -0
- data/lib/byebug/commands/continue.rb +68 -0
- data/lib/byebug/commands/debug.rb +38 -0
- data/lib/byebug/commands/delete.rb +55 -0
- data/lib/byebug/commands/disable/breakpoints.rb +42 -0
- data/lib/byebug/commands/disable/display.rb +43 -0
- data/lib/byebug/commands/disable.rb +33 -0
- data/lib/byebug/commands/display.rb +66 -0
- data/lib/byebug/commands/down.rb +45 -0
- data/lib/byebug/commands/edit.rb +69 -0
- data/lib/byebug/commands/enable/breakpoints.rb +42 -0
- data/lib/byebug/commands/enable/display.rb +43 -0
- data/lib/byebug/commands/enable.rb +33 -0
- data/lib/byebug/commands/finish.rb +57 -0
- data/lib/byebug/commands/frame.rb +57 -0
- data/lib/byebug/commands/help.rb +64 -0
- data/lib/byebug/commands/history.rb +39 -0
- data/lib/byebug/commands/info/breakpoints.rb +65 -0
- data/lib/byebug/commands/info/display.rb +49 -0
- data/lib/byebug/commands/info/file.rb +80 -0
- data/lib/byebug/commands/info/line.rb +35 -0
- data/lib/byebug/commands/info/program.rb +49 -0
- data/lib/byebug/commands/info.rb +37 -0
- data/lib/byebug/commands/interrupt.rb +34 -0
- data/lib/byebug/commands/irb.rb +50 -0
- data/lib/byebug/commands/kill.rb +45 -0
- data/lib/byebug/commands/list.rb +159 -0
- data/lib/byebug/commands/method.rb +53 -0
- data/lib/byebug/commands/next.rb +40 -0
- data/lib/byebug/commands/pry.rb +41 -0
- data/lib/byebug/commands/quit.rb +42 -0
- data/lib/byebug/commands/restart.rb +64 -0
- data/lib/byebug/commands/save.rb +72 -0
- data/lib/byebug/commands/set.rb +79 -0
- data/lib/byebug/commands/show.rb +45 -0
- data/lib/byebug/commands/skip.rb +85 -0
- data/lib/byebug/commands/source.rb +40 -0
- data/lib/byebug/commands/step.rb +40 -0
- data/lib/byebug/commands/thread/current.rb +37 -0
- data/lib/byebug/commands/thread/list.rb +43 -0
- data/lib/byebug/commands/thread/resume.rb +45 -0
- data/lib/byebug/commands/thread/stop.rb +43 -0
- data/lib/byebug/commands/thread/switch.rb +46 -0
- data/lib/byebug/commands/thread.rb +34 -0
- data/lib/byebug/commands/tracevar.rb +54 -0
- data/lib/byebug/commands/undisplay.rb +51 -0
- data/lib/byebug/commands/untracevar.rb +36 -0
- data/lib/byebug/commands/up.rb +45 -0
- data/lib/byebug/commands/var/all.rb +41 -0
- data/lib/byebug/commands/var/args.rb +39 -0
- data/lib/byebug/commands/var/const.rb +49 -0
- data/lib/byebug/commands/var/global.rb +37 -0
- data/lib/byebug/commands/var/instance.rb +39 -0
- data/lib/byebug/commands/var/local.rb +39 -0
- data/lib/byebug/commands/var.rb +37 -0
- data/lib/byebug/commands/where.rb +64 -0
- data/lib/byebug/commands.rb +40 -0
- data/lib/byebug/context.rb +157 -0
- data/lib/byebug/core.rb +115 -0
- data/lib/byebug/errors.rb +29 -0
- data/lib/byebug/frame.rb +185 -0
- data/lib/byebug/helpers/bin.rb +47 -0
- data/lib/byebug/helpers/eval.rb +134 -0
- data/lib/byebug/helpers/file.rb +63 -0
- data/lib/byebug/helpers/frame.rb +75 -0
- data/lib/byebug/helpers/parse.rb +80 -0
- data/lib/byebug/helpers/path.rb +40 -0
- data/lib/byebug/helpers/reflection.rb +19 -0
- data/lib/byebug/helpers/string.rb +33 -0
- data/lib/byebug/helpers/thread.rb +67 -0
- data/lib/byebug/helpers/toggle.rb +62 -0
- data/lib/byebug/helpers/var.rb +70 -0
- data/lib/byebug/history.rb +130 -0
- data/lib/byebug/interface.rb +146 -0
- data/lib/byebug/interfaces/local_interface.rb +63 -0
- data/lib/byebug/interfaces/remote_interface.rb +50 -0
- data/lib/byebug/interfaces/script_interface.rb +33 -0
- data/lib/byebug/interfaces/test_interface.rb +67 -0
- data/lib/byebug/option_setter.rb +95 -0
- data/lib/byebug/printers/base.rb +68 -0
- data/lib/byebug/printers/plain.rb +44 -0
- data/lib/byebug/printers/texts/base.yml +115 -0
- data/lib/byebug/printers/texts/plain.yml +33 -0
- data/lib/byebug/processors/command_processor.rb +173 -0
- data/lib/byebug/processors/control_processor.rb +24 -0
- data/lib/byebug/processors/post_mortem_processor.rb +18 -0
- data/lib/byebug/processors/script_processor.rb +49 -0
- data/lib/byebug/remote/client.rb +57 -0
- data/lib/byebug/remote/server.rb +47 -0
- data/lib/byebug/remote.rb +85 -0
- data/lib/byebug/runner.rb +198 -0
- data/lib/byebug/setting.rb +79 -0
- data/lib/byebug/settings/autoirb.rb +29 -0
- data/lib/byebug/settings/autolist.rb +29 -0
- data/lib/byebug/settings/autopry.rb +29 -0
- data/lib/byebug/settings/autosave.rb +17 -0
- data/lib/byebug/settings/basename.rb +16 -0
- data/lib/byebug/settings/callstyle.rb +20 -0
- data/lib/byebug/settings/fullpath.rb +16 -0
- data/lib/byebug/settings/histfile.rb +20 -0
- data/lib/byebug/settings/histsize.rb +20 -0
- data/lib/byebug/settings/linetrace.rb +22 -0
- data/lib/byebug/settings/listsize.rb +21 -0
- data/lib/byebug/settings/post_mortem.rb +27 -0
- data/lib/byebug/settings/savefile.rb +20 -0
- data/lib/byebug/settings/stack_on_error.rb +15 -0
- data/lib/byebug/settings/width.rb +20 -0
- data/lib/byebug/source_file_formatter.rb +71 -0
- data/lib/byebug/subcommands.rb +54 -0
- data/lib/byebug/version.rb +8 -0
- data/lib/byebug.rb +3 -0
- metadata +194 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/eval"
|
5
|
+
require_relative "../helpers/file"
|
6
|
+
require_relative "../helpers/parse"
|
7
|
+
require_relative "../source_file_formatter"
|
8
|
+
|
9
|
+
module Byebug
|
10
|
+
#
|
11
|
+
# Implements breakpoint functionality
|
12
|
+
#
|
13
|
+
class BreakCommand < Command
|
14
|
+
include Helpers::EvalHelper
|
15
|
+
include Helpers::FileHelper
|
16
|
+
include Helpers::ParseHelper
|
17
|
+
|
18
|
+
self.allow_in_control = true
|
19
|
+
|
20
|
+
def self.regexp
|
21
|
+
/^\s* b(?:reak)? (?:\s+ (.+?))? (?:\s+ if \s+(.+))? \s*$/x
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.description
|
25
|
+
<<-DESCRIPTION
|
26
|
+
b[reak] [[<file>:]<line> [if <expr>]]
|
27
|
+
b[reak] [<module>::...]<class>(.|#)<method> [if <expr>]
|
28
|
+
|
29
|
+
#{short_description}
|
30
|
+
|
31
|
+
They can be specified by line or method and an expression can be added
|
32
|
+
for conditionally enabled breakpoints.
|
33
|
+
for conditionally enabled breakpoints. Without arguments create a
|
34
|
+
a breakpoint in the current line.
|
35
|
+
DESCRIPTION
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.short_description
|
39
|
+
"Sets breakpoints in the source code"
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute
|
43
|
+
b = line_breakpoint(frame.line.to_s) unless @match[1]
|
44
|
+
|
45
|
+
b ||= line_breakpoint(@match[1]) || method_breakpoint(@match[1])
|
46
|
+
return errmsg(pr("break.errors.location")) unless b
|
47
|
+
|
48
|
+
return puts(pr("break.created", id: b.id, file: b.source, line: b.pos)) if syntax_valid?(@match[2])
|
49
|
+
|
50
|
+
errmsg(pr("break.errors.expression", expr: @match[2]))
|
51
|
+
b.enabled = false
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def line_breakpoint(location)
|
57
|
+
line_match = location.match(/^(\d+)$/)
|
58
|
+
file_line_match = location.match(/^(.+):(\d+)$/)
|
59
|
+
return unless line_match || file_line_match
|
60
|
+
|
61
|
+
file = line_match ? frame.file : file_line_match[1]
|
62
|
+
line = line_match ? line_match[1].to_i : file_line_match[2].to_i
|
63
|
+
|
64
|
+
add_line_breakpoint(file, line)
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_breakpoint(location)
|
68
|
+
location.match(/([^.#]+)[.#](.+)/) do |match|
|
69
|
+
klass = target_object(match[1])
|
70
|
+
method = match[2].intern
|
71
|
+
|
72
|
+
Breakpoint.add(klass, method, @match[2])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def target_object(str)
|
77
|
+
k = error_eval(str)
|
78
|
+
|
79
|
+
k&.is_a?(Module) ? k.name : str
|
80
|
+
rescue StandardError
|
81
|
+
errmsg("Warning: breakpoint source is not yet defined")
|
82
|
+
str
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_line_breakpoint(file, line)
|
86
|
+
raise(pr("break.errors.source", file: file)) unless File.exist?(file)
|
87
|
+
|
88
|
+
fullpath = File.realpath(file)
|
89
|
+
|
90
|
+
raise(pr("break.errors.far_line", lines: n_lines(file), file: fullpath)) if line > n_lines(file)
|
91
|
+
|
92
|
+
unless Breakpoint.potential_line?(fullpath, line)
|
93
|
+
msg = pr(
|
94
|
+
"break.errors.line",
|
95
|
+
file: fullpath,
|
96
|
+
line: line,
|
97
|
+
valid_breakpoints: valid_breakpoints_for(fullpath, line)
|
98
|
+
)
|
99
|
+
|
100
|
+
raise(msg)
|
101
|
+
end
|
102
|
+
|
103
|
+
Breakpoint.add(fullpath, line, @match[2])
|
104
|
+
end
|
105
|
+
|
106
|
+
def valid_breakpoints_for(path, line)
|
107
|
+
potential_lines = Breakpoint.potential_lines(path)
|
108
|
+
annotator = ->(n) { potential_lines.include?(n) ? "[B]" : " " }
|
109
|
+
source_file_formatter = SourceFileFormatter.new(path, annotator)
|
110
|
+
|
111
|
+
source_file_formatter.lines_around(line).join.chomp
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/eval"
|
5
|
+
|
6
|
+
module Byebug
|
7
|
+
#
|
8
|
+
# Implements exception catching.
|
9
|
+
#
|
10
|
+
# Enables the user to catch unhandled assertion when they happen.
|
11
|
+
#
|
12
|
+
class CatchCommand < Command
|
13
|
+
include Helpers::EvalHelper
|
14
|
+
|
15
|
+
self.allow_in_post_mortem = true
|
16
|
+
|
17
|
+
def self.regexp
|
18
|
+
/^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.description
|
22
|
+
<<-DESCRIPTION
|
23
|
+
cat[ch][ (off|<exception>[ off])]
|
24
|
+
|
25
|
+
#{short_description}
|
26
|
+
|
27
|
+
catch -- lists catchpoints
|
28
|
+
catch off -- deletes all catchpoints
|
29
|
+
catch <exception> -- enables handling <exception>
|
30
|
+
catch <exception> off -- disables handling <exception>
|
31
|
+
DESCRIPTION
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.short_description
|
35
|
+
"Handles exception catchpoints"
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute
|
39
|
+
return info unless @match[1]
|
40
|
+
|
41
|
+
return @match[1] == "off" ? clear : add(@match[1]) unless @match[2]
|
42
|
+
|
43
|
+
return errmsg pr("catch.errors.off", off: cmd) unless @match[2] == "off"
|
44
|
+
|
45
|
+
remove(@match[1])
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def remove(exception)
|
51
|
+
return errmsg pr("catch.errors.not_found", exception: exception) unless Byebug.catchpoints.member?(exception)
|
52
|
+
|
53
|
+
puts pr("catch.removed", exception: exception)
|
54
|
+
Byebug.catchpoints.delete(exception)
|
55
|
+
end
|
56
|
+
|
57
|
+
def add(exception)
|
58
|
+
errmsg pr("catch.errors.not_class", class: exception) if warning_eval(exception.is_a?(Class).to_s)
|
59
|
+
|
60
|
+
puts pr("catch.added", exception: exception)
|
61
|
+
Byebug.add_catchpoint(exception)
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear
|
65
|
+
Byebug.catchpoints.clear if confirm(pr("catch.confirmations.delete_all"))
|
66
|
+
end
|
67
|
+
|
68
|
+
def info
|
69
|
+
if Byebug.catchpoints && !Byebug.catchpoints.empty?
|
70
|
+
Byebug.catchpoints.each_key do |exception|
|
71
|
+
puts("#{exception}: #{exception.is_a?(Class)}")
|
72
|
+
end
|
73
|
+
else
|
74
|
+
puts "No exceptions set to be caught."
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/parse"
|
5
|
+
|
6
|
+
module Byebug
|
7
|
+
#
|
8
|
+
# Implements conditions on breakpoints.
|
9
|
+
#
|
10
|
+
# Adds the ability to stop on breakpoints only under certain conditions.
|
11
|
+
#
|
12
|
+
class ConditionCommand < Command
|
13
|
+
include Helpers::ParseHelper
|
14
|
+
|
15
|
+
self.allow_in_post_mortem = true
|
16
|
+
|
17
|
+
def self.regexp
|
18
|
+
/^\s* cond(?:ition)? (?:\s+(\d+)(?:\s+(.*))?)? \s*$/x
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.description
|
22
|
+
<<-DESCRIPTION
|
23
|
+
cond[ition] <n>[ expr]
|
24
|
+
|
25
|
+
#{short_description}
|
26
|
+
|
27
|
+
Specify breakpoint number <n> to break only if <expr> is true. <n> is
|
28
|
+
an integer and <expr> is an expression to be evaluated whenever
|
29
|
+
breakpoint <n> is reached. If no expression is specified, the condition
|
30
|
+
is removed.
|
31
|
+
DESCRIPTION
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.short_description
|
35
|
+
"Sets conditions on breakpoints"
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute
|
39
|
+
return puts(help) unless @match[1]
|
40
|
+
|
41
|
+
breakpoints = Byebug.breakpoints.sort_by(&:id)
|
42
|
+
return errmsg(pr("condition.errors.no_breakpoints")) if breakpoints.empty?
|
43
|
+
|
44
|
+
pos, err = get_int(@match[1], "Condition", 1)
|
45
|
+
return errmsg(err) if err
|
46
|
+
|
47
|
+
breakpoint = breakpoints.find { |b| b.id == pos }
|
48
|
+
return errmsg(pr("break.errors.no_breakpoint")) unless breakpoint
|
49
|
+
|
50
|
+
return errmsg(pr("break.errors.not_changed", expr: @match[2])) unless syntax_valid?(@match[2])
|
51
|
+
|
52
|
+
breakpoint.expr = @match[2]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/parse"
|
5
|
+
|
6
|
+
module Byebug
|
7
|
+
#
|
8
|
+
# Implements the continue command.
|
9
|
+
#
|
10
|
+
# Allows the user to continue execution until the next stopping point, a
|
11
|
+
# specific line number or until program termination.
|
12
|
+
#
|
13
|
+
class ContinueCommand < Command
|
14
|
+
include Helpers::ParseHelper
|
15
|
+
|
16
|
+
def self.regexp
|
17
|
+
/^\s* c(?:ont(?:inue)?)? (?:(!|\s+unconditionally|\s+\S+))? \s*$/x
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.description
|
21
|
+
<<-DESCRIPTION
|
22
|
+
c[ont[inue]][ <line_number>]
|
23
|
+
|
24
|
+
#{short_description}
|
25
|
+
|
26
|
+
Normally the program stops at the next breakpoint. However, if the
|
27
|
+
parameter "unconditionally" is given or the command is suffixed with
|
28
|
+
"!", the program will run until the end regardless of any enabled
|
29
|
+
breakpoints.
|
30
|
+
DESCRIPTION
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.short_description
|
34
|
+
"Runs until program ends, hits a breakpoint or reaches a line"
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute
|
38
|
+
if until_line?
|
39
|
+
num, err = get_int(modifier, "Continue", 0, nil)
|
40
|
+
return errmsg(err) unless num
|
41
|
+
|
42
|
+
filename = File.expand_path(frame.file)
|
43
|
+
return errmsg(pr("continue.errors.unstopped_line", line: num)) unless Breakpoint.potential_line?(filename, num)
|
44
|
+
|
45
|
+
Breakpoint.add(filename, num)
|
46
|
+
end
|
47
|
+
|
48
|
+
processor.proceed!
|
49
|
+
|
50
|
+
Byebug.mode = :off if unconditionally?
|
51
|
+
Byebug.stop if unconditionally? || Byebug.stoppable?
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def until_line?
|
57
|
+
@match[1] && !["!", "unconditionally"].include?(modifier)
|
58
|
+
end
|
59
|
+
|
60
|
+
def unconditionally?
|
61
|
+
@match[1] && ["!", "unconditionally"].include?(modifier)
|
62
|
+
end
|
63
|
+
|
64
|
+
def modifier
|
65
|
+
@match[1].lstrip
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/eval"
|
5
|
+
|
6
|
+
module Byebug
|
7
|
+
#
|
8
|
+
# Spawns a subdebugger and evaluates the given expression
|
9
|
+
#
|
10
|
+
class DebugCommand < Command
|
11
|
+
include Helpers::EvalHelper
|
12
|
+
|
13
|
+
def self.regexp
|
14
|
+
/^\s* debug (?:\s+(\S+))? \s*$/x
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.description
|
18
|
+
<<-DESCRIPTION
|
19
|
+
debug <expression>
|
20
|
+
|
21
|
+
#{short_description}
|
22
|
+
|
23
|
+
Allows, for example, setting breakpoints on expressions evaluated from
|
24
|
+
the debugger's prompt.
|
25
|
+
DESCRIPTION
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.short_description
|
29
|
+
"Spawns a subdebugger"
|
30
|
+
end
|
31
|
+
|
32
|
+
def execute
|
33
|
+
return puts(help) unless @match[1]
|
34
|
+
|
35
|
+
puts safe_inspect(separate_thread_eval(@match[1]))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/parse"
|
5
|
+
|
6
|
+
module Byebug
|
7
|
+
#
|
8
|
+
# Implements breakpoint deletion.
|
9
|
+
#
|
10
|
+
class DeleteCommand < Command
|
11
|
+
include Helpers::ParseHelper
|
12
|
+
|
13
|
+
self.allow_in_control = true
|
14
|
+
self.allow_in_post_mortem = true
|
15
|
+
|
16
|
+
def self.regexp
|
17
|
+
/^\s* del(?:ete)? (?:\s+(.*))?$/x
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.description
|
21
|
+
<<-DESCRIPTION
|
22
|
+
del[ete][ nnn...]
|
23
|
+
|
24
|
+
#{short_description}
|
25
|
+
|
26
|
+
Without and argument, deletes all breakpoints. With integer arguments,
|
27
|
+
it deletes specific breakpoints.
|
28
|
+
DESCRIPTION
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.short_description
|
32
|
+
"Deletes breakpoints"
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute
|
36
|
+
unless @match[1]
|
37
|
+
Byebug.breakpoints.clear if confirm(pr("break.confirmations.delete_all"))
|
38
|
+
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
42
|
+
@match[1].split(/ +/).each do |number|
|
43
|
+
pos, err = get_int(number, "Delete", 1)
|
44
|
+
|
45
|
+
return errmsg(err) unless pos
|
46
|
+
|
47
|
+
if Breakpoint.remove(pos)
|
48
|
+
puts(pr("break.messages.breakpoint_deleted", pos: pos))
|
49
|
+
else
|
50
|
+
errmsg(pr("break.errors.no_breakpoint_delete", pos: pos))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../helpers/toggle"
|
4
|
+
|
5
|
+
module Byebug
|
6
|
+
#
|
7
|
+
# Reopens the +disable+ command to define the +breakpoints+ subcommand
|
8
|
+
#
|
9
|
+
class DisableCommand < Command
|
10
|
+
#
|
11
|
+
# Disables all or specific breakpoints
|
12
|
+
#
|
13
|
+
class BreakpointsCommand < Command
|
14
|
+
include Helpers::ToggleHelper
|
15
|
+
|
16
|
+
self.allow_in_post_mortem = true
|
17
|
+
|
18
|
+
def self.regexp
|
19
|
+
/^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.description
|
23
|
+
<<-DESCRIPTION
|
24
|
+
dis[able] b[reakpoints][ <id1> <id2> .. <idn>]
|
25
|
+
|
26
|
+
#{short_description}
|
27
|
+
|
28
|
+
Give breakpoint numbers (separated by spaces) as arguments or no
|
29
|
+
argument at all if you want to disable every breakpoint.
|
30
|
+
DESCRIPTION
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.short_description
|
34
|
+
"Disable all or specific breakpoints."
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute
|
38
|
+
enable_disable_breakpoints("disable", @match[1])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../helpers/toggle"
|
4
|
+
|
5
|
+
module Byebug
|
6
|
+
#
|
7
|
+
# Reopens the +disable+ command to define the +display+ subcommand
|
8
|
+
#
|
9
|
+
class DisableCommand < Command
|
10
|
+
#
|
11
|
+
# Enables all or specific displays
|
12
|
+
#
|
13
|
+
class DisplayCommand < Command
|
14
|
+
include Helpers::ToggleHelper
|
15
|
+
|
16
|
+
self.allow_in_post_mortem = true
|
17
|
+
|
18
|
+
def self.regexp
|
19
|
+
/^\s* d(?:isplay)? (?:\s+ (.+))? \s*$/x
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.description
|
23
|
+
<<-DESCRIPTION
|
24
|
+
dis[able] d[isplay][ <id1> <id2> .. <idn>]
|
25
|
+
|
26
|
+
#{short_description}
|
27
|
+
|
28
|
+
Arguments are the code numbers of the expressions to disable. Do "info
|
29
|
+
display" to see the current list of code numbers. If no arguments are
|
30
|
+
specified, all displays are disabled.
|
31
|
+
DESCRIPTION
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.short_description
|
35
|
+
"Disables expressions to be displayed when program stops."
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute
|
39
|
+
enable_disable_display("disable", @match[1])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../subcommands"
|
4
|
+
|
5
|
+
require_relative "../commands/disable/breakpoints"
|
6
|
+
require_relative "../commands/disable/display"
|
7
|
+
|
8
|
+
module Byebug
|
9
|
+
#
|
10
|
+
# Disabling custom display expressions or breakpoints.
|
11
|
+
#
|
12
|
+
class DisableCommand < Command
|
13
|
+
include Subcommands
|
14
|
+
|
15
|
+
self.allow_in_post_mortem = true
|
16
|
+
|
17
|
+
def self.regexp
|
18
|
+
/^\s* dis(?:able)? (?:\s+ (.+))? \s*$/x
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.description
|
22
|
+
<<-DESCRIPTION
|
23
|
+
dis[able][[ breakpoints| display)][ n1[ n2[ ...[ nn]]]]]
|
24
|
+
|
25
|
+
#{short_description}
|
26
|
+
DESCRIPTION
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.short_description
|
30
|
+
"Disables breakpoints or displays"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../command"
|
4
|
+
require_relative "../helpers/eval"
|
5
|
+
|
6
|
+
module Byebug
|
7
|
+
#
|
8
|
+
# Custom expressions to be displayed every time the debugger stops.
|
9
|
+
#
|
10
|
+
class DisplayCommand < Command
|
11
|
+
include Helpers::EvalHelper
|
12
|
+
|
13
|
+
self.allow_in_post_mortem = false
|
14
|
+
self.always_run = 2
|
15
|
+
|
16
|
+
def self.regexp
|
17
|
+
/^\s* disp(?:lay)? (?:\s+ (.+))? \s*$/x
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.description
|
21
|
+
<<-DESCRIPTION
|
22
|
+
disp[lay][ <expression>]
|
23
|
+
|
24
|
+
#{short_description}
|
25
|
+
|
26
|
+
If <expression> specified, adds <expression> into display expression
|
27
|
+
list. Otherwise, it lists all expressions.
|
28
|
+
DESCRIPTION
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.short_description
|
32
|
+
"Evaluates expressions every time the debugger stops"
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute
|
36
|
+
return print_display_expressions unless @match && @match[1]
|
37
|
+
|
38
|
+
Byebug.displays.push [true, @match[1]]
|
39
|
+
display_expression(@match[1])
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def display_expression(exp)
|
45
|
+
print pr("display.result", n: Byebug.displays.size,
|
46
|
+
exp: exp,
|
47
|
+
result: eval_expr(exp))
|
48
|
+
end
|
49
|
+
|
50
|
+
def print_display_expressions
|
51
|
+
result = prc("display.result", Byebug.displays) do |item, index|
|
52
|
+
active, exp = item
|
53
|
+
|
54
|
+
{ n: index + 1, exp: exp, result: eval_expr(exp) } if active
|
55
|
+
end
|
56
|
+
|
57
|
+
print result
|
58
|
+
end
|
59
|
+
|
60
|
+
def eval_expr(expression)
|
61
|
+
error_eval(expression).inspect
|
62
|
+
rescue StandardError
|
63
|
+
"(undefined)"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require_relative "../command"
|
5
|
+
require_relative "../helpers/frame"
|
6
|
+
require_relative "../helpers/parse"
|
7
|
+
|
8
|
+
module Byebug
|
9
|
+
#
|
10
|
+
# Move the current frame down in the backtrace.
|
11
|
+
#
|
12
|
+
class DownCommand < Command
|
13
|
+
include Helpers::FrameHelper
|
14
|
+
include Helpers::ParseHelper
|
15
|
+
|
16
|
+
self.allow_in_post_mortem = true
|
17
|
+
|
18
|
+
def self.regexp
|
19
|
+
/^\s* down (?:\s+(\S+))? \s*$/x
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.description
|
23
|
+
<<-DESCRIPTION
|
24
|
+
down[ count]
|
25
|
+
|
26
|
+
#{short_description}
|
27
|
+
|
28
|
+
Use the "bt" command to find out where you want to go.
|
29
|
+
DESCRIPTION
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.short_description
|
33
|
+
"Moves to a lower frame in the stack trace"
|
34
|
+
end
|
35
|
+
|
36
|
+
def execute
|
37
|
+
pos, err = parse_steps(@match[1], "Down")
|
38
|
+
return errmsg(err) unless pos
|
39
|
+
|
40
|
+
jump_frames(-pos)
|
41
|
+
|
42
|
+
ListCommand.new(processor).execute if Setting[:autolist]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|