byebug 3.5.1 → 4.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 +4 -1
- data/.rubocop.yml +18 -1
- data/.travis.yml +21 -1
- data/CHANGELOG.md +356 -308
- data/CONTRIBUTING.md +31 -15
- data/GUIDE.md +859 -475
- data/Gemfile +8 -10
- data/LICENSE +1 -1
- data/README.md +41 -45
- data/Rakefile +30 -28
- data/byebug.gemspec +18 -18
- data/ext/byebug/breakpoint.c +88 -75
- data/ext/byebug/byebug.c +253 -252
- data/ext/byebug/byebug.h +53 -53
- data/ext/byebug/context.c +188 -159
- data/ext/byebug/extconf.rb +9 -6
- data/ext/byebug/locker.c +53 -11
- data/ext/byebug/threads.c +137 -39
- data/lib/byebug/attacher.rb +7 -2
- data/lib/byebug/breakpoint.rb +30 -0
- data/lib/byebug/command.rb +36 -32
- data/lib/byebug/commands/break.rb +49 -48
- data/lib/byebug/commands/catch.rb +64 -0
- data/lib/byebug/commands/condition.rb +13 -9
- data/lib/byebug/commands/continue.rb +8 -4
- data/lib/byebug/commands/delete.rb +10 -4
- data/lib/byebug/commands/display.rb +33 -25
- data/lib/byebug/commands/edit.rb +18 -13
- data/lib/byebug/commands/enable_disable.rb +26 -24
- data/lib/byebug/commands/eval.rb +77 -35
- data/lib/byebug/commands/finish.rb +9 -5
- data/lib/byebug/commands/frame.rb +66 -125
- data/lib/byebug/commands/help.rb +14 -21
- data/lib/byebug/commands/history.rb +5 -1
- data/lib/byebug/commands/info.rb +41 -106
- data/lib/byebug/commands/interrupt.rb +6 -2
- data/lib/byebug/commands/irb.rb +5 -2
- data/lib/byebug/commands/kill.rb +6 -2
- data/lib/byebug/commands/list.rb +21 -14
- data/lib/byebug/commands/method.rb +17 -9
- data/lib/byebug/commands/pry.rb +13 -3
- data/lib/byebug/commands/quit.rb +10 -5
- data/lib/byebug/commands/restart.rb +12 -19
- data/lib/byebug/commands/save.rb +10 -6
- data/lib/byebug/commands/set.rb +15 -14
- data/lib/byebug/commands/show.rb +8 -8
- data/lib/byebug/commands/source.rb +14 -8
- data/lib/byebug/commands/stepping.rb +15 -29
- data/lib/byebug/commands/threads.rb +73 -49
- data/lib/byebug/commands/tracevar.rb +56 -0
- data/lib/byebug/commands/undisplay.rb +8 -4
- data/lib/byebug/commands/untracevar.rb +38 -0
- data/lib/byebug/commands/var.rb +107 -0
- data/lib/byebug/context.rb +78 -42
- data/lib/byebug/core.rb +78 -40
- data/lib/byebug/helper.rb +58 -42
- data/lib/byebug/history.rb +12 -1
- data/lib/byebug/interface.rb +91 -11
- data/lib/byebug/interfaces/local_interface.rb +12 -19
- data/lib/byebug/interfaces/remote_interface.rb +12 -15
- data/lib/byebug/interfaces/script_interface.rb +14 -18
- data/lib/byebug/interfaces/test_interface.rb +54 -0
- data/lib/byebug/printers/base.rb +64 -0
- data/lib/byebug/printers/plain.rb +53 -0
- data/lib/byebug/processor.rb +20 -1
- data/lib/byebug/processors/command_processor.rb +57 -172
- data/lib/byebug/processors/control_command_processor.rb +16 -43
- data/lib/byebug/remote.rb +13 -7
- data/lib/byebug/runner.rb +102 -54
- data/lib/byebug/setting.rb +45 -68
- data/lib/byebug/settings/autoeval.rb +2 -0
- data/lib/byebug/settings/autoirb.rb +3 -0
- data/lib/byebug/settings/autolist.rb +3 -0
- data/lib/byebug/settings/autosave.rb +2 -0
- data/lib/byebug/settings/basename.rb +2 -0
- data/lib/byebug/settings/callstyle.rb +2 -0
- data/lib/byebug/settings/fullpath.rb +2 -0
- data/lib/byebug/settings/histfile.rb +2 -0
- data/lib/byebug/settings/histsize.rb +2 -0
- data/lib/byebug/settings/linetrace.rb +2 -0
- data/lib/byebug/settings/listsize.rb +2 -0
- data/lib/byebug/settings/post_mortem.rb +7 -2
- data/lib/byebug/settings/stack_on_error.rb +2 -0
- data/lib/byebug/settings/verbose.rb +2 -0
- data/lib/byebug/settings/width.rb +2 -0
- data/lib/byebug/state.rb +12 -0
- data/lib/byebug/states/control_state.rb +26 -0
- data/lib/byebug/states/regular_state.rb +178 -0
- data/lib/byebug/version.rb +1 -1
- metadata +24 -109
- data/lib/byebug/commands/catchpoint.rb +0 -53
- data/lib/byebug/commands/reload.rb +0 -29
- data/lib/byebug/commands/trace.rb +0 -50
- data/lib/byebug/commands/variables.rb +0 -206
- data/lib/byebug/options.rb +0 -46
- data/lib/byebug/settings/autoreload.rb +0 -12
- data/lib/byebug/settings/forcestep.rb +0 -14
- data/lib/byebug/settings/testing.rb +0 -12
- data/lib/byebug/settings/tracing_plus.rb +0 -11
- data/test/commands/break_test.rb +0 -364
- data/test/commands/condition_test.rb +0 -85
- data/test/commands/continue_test.rb +0 -47
- data/test/commands/delete_test.rb +0 -26
- data/test/commands/display_test.rb +0 -37
- data/test/commands/edit_test.rb +0 -52
- data/test/commands/eval_test.rb +0 -89
- data/test/commands/finish_test.rb +0 -74
- data/test/commands/frame_test.rb +0 -223
- data/test/commands/help_test.rb +0 -66
- data/test/commands/history_test.rb +0 -61
- data/test/commands/info_test.rb +0 -238
- data/test/commands/interrupt_test.rb +0 -45
- data/test/commands/irb_test.rb +0 -28
- data/test/commands/kill_test.rb +0 -50
- data/test/commands/list_test.rb +0 -174
- data/test/commands/method_test.rb +0 -52
- data/test/commands/post_mortem_test.rb +0 -71
- data/test/commands/pry_test.rb +0 -26
- data/test/commands/quit_test.rb +0 -53
- data/test/commands/reload_test.rb +0 -39
- data/test/commands/restart_test.rb +0 -46
- data/test/commands/save_test.rb +0 -67
- data/test/commands/set_test.rb +0 -140
- data/test/commands/show_test.rb +0 -76
- data/test/commands/source_test.rb +0 -46
- data/test/commands/stepping_test.rb +0 -192
- data/test/commands/thread_test.rb +0 -164
- data/test/commands/trace_test.rb +0 -71
- data/test/commands/undisplay_test.rb +0 -75
- data/test/commands/variables_test.rb +0 -105
- data/test/debugger_alias_test.rb +0 -7
- data/test/runner_test.rb +0 -150
- data/test/support/matchers.rb +0 -65
- data/test/support/test_interface.rb +0 -59
- data/test/support/utils.rb +0 -122
- data/test/test_helper.rb +0 -58
@@ -1,12 +1,14 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
1
3
|
module Byebug
|
2
4
|
#
|
3
5
|
# Mixin to assist command parsing
|
4
6
|
#
|
5
7
|
module EnableDisableFunctions
|
6
8
|
def enable_disable_breakpoints(is_enable, args)
|
7
|
-
return errmsg('
|
9
|
+
return errmsg(pr('toggle.errors.no_breakpoints')) if Breakpoint.none?
|
8
10
|
|
9
|
-
all_breakpoints = Byebug.breakpoints.sort_by
|
11
|
+
all_breakpoints = Byebug.breakpoints.sort_by(&:id)
|
10
12
|
if args.empty?
|
11
13
|
selected_breakpoints = all_breakpoints
|
12
14
|
else
|
@@ -18,16 +20,15 @@ module Byebug
|
|
18
20
|
|
19
21
|
selected_ids << pos
|
20
22
|
end
|
21
|
-
selected_breakpoints = all_breakpoints.select do
|
22
|
-
|
23
|
+
selected_breakpoints = all_breakpoints.select do |b|
|
24
|
+
selected_ids.include?(b.id)
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
28
|
selected_breakpoints.each do |b|
|
27
29
|
enabled = ('enable' == is_enable)
|
28
30
|
if enabled && !syntax_valid?(b.expr)
|
29
|
-
return errmsg(
|
30
|
-
'breakpoint remains disabled.')
|
31
|
+
return errmsg(pr('toggle.errors.expression', expr: b.expr))
|
31
32
|
end
|
32
33
|
|
33
34
|
b.enabled = enabled
|
@@ -35,9 +36,7 @@ module Byebug
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def enable_disable_display(is_enable, args)
|
38
|
-
if 0 == @state.display.size
|
39
|
-
return errmsg('No display expressions have been set')
|
40
|
-
end
|
39
|
+
return errmsg(pr('toggle.errors.no_display')) if 0 == @state.display.size
|
41
40
|
|
42
41
|
args.each do |pos|
|
43
42
|
pos, err = get_int(pos, "#{is_enable} display", 1, @state.display.size)
|
@@ -52,6 +51,8 @@ module Byebug
|
|
52
51
|
# Enabling or disabling custom display expressions or breakpoints.
|
53
52
|
#
|
54
53
|
class EnableDisableCommand < Command
|
54
|
+
include EnableDisableFunctions
|
55
|
+
|
55
56
|
Subcommands = [
|
56
57
|
['breakpoints', 2, 'Enable/disable breakpoints. Give breakpoint ' \
|
57
58
|
'numbers (separated by spaces) as arguments or no ' \
|
@@ -64,7 +65,7 @@ module Byebug
|
|
64
65
|
'numbers']
|
65
66
|
].map do |name, min, help|
|
66
67
|
Subcmd.new(name, min, help)
|
67
|
-
end
|
68
|
+
end
|
68
69
|
|
69
70
|
def regexp
|
70
71
|
/^\s* (dis|en)(?:able)? (?:\s+(.+))? \s*$/x
|
@@ -73,8 +74,7 @@ module Byebug
|
|
73
74
|
def execute
|
74
75
|
cmd = @match[1] == 'dis' ? 'disable' : 'enable'
|
75
76
|
|
76
|
-
return errmsg(
|
77
|
-
"\"breakpoints\" or breakpoint ids") unless @match[2]
|
77
|
+
return errmsg(pr('toggle.errors.syntax', toggle: cmd)) unless @match[2]
|
78
78
|
|
79
79
|
args = @match[2].split(/[ \t]+/)
|
80
80
|
param = args.shift
|
@@ -108,22 +108,24 @@ module Byebug
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def description
|
111
|
-
|
111
|
+
prettify <<-EOD
|
112
|
+
(en|dis)[able][[ (breakpoints|display)][ n1[ n2[ ...[ nn]]]]]
|
112
113
|
|
113
|
-
|
114
|
+
Enables or disables breakpoints or displays.
|
114
115
|
|
115
|
-
|
116
|
-
|
117
|
-
|
116
|
+
"enable" by itself enables all breakpoints, just like
|
117
|
+
"enable breakpoints". On the other side, "disable" or
|
118
|
+
"disable breakpoints" disable all breakpoints.
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
You can also specify a space separated list of breakpoint numbers to
|
121
|
+
enable or disable specific breakpoints. You can use either
|
122
|
+
"enable <id1> ... <idn>" or "enable breakpoints <id1> ... <idn>" and
|
123
|
+
the same with "disable".
|
123
124
|
|
124
|
-
|
125
|
-
|
126
|
-
|
125
|
+
If instead of "breakpoints" you specify "display", the command will
|
126
|
+
work exactly the same way, but displays will get enabled/disabled
|
127
|
+
instead of breakpoints.
|
128
|
+
EOD
|
127
129
|
end
|
128
130
|
end
|
129
131
|
end
|
data/lib/byebug/commands/eval.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
1
3
|
require 'English'
|
2
4
|
require 'pp'
|
3
5
|
|
@@ -6,16 +8,52 @@ module Byebug
|
|
6
8
|
# Utilities used by the eval command
|
7
9
|
#
|
8
10
|
module EvalFunctions
|
11
|
+
#
|
12
|
+
# Run block temporarily ignoring all TracePoint events.
|
13
|
+
#
|
14
|
+
# Used to evaluate stuff within Byebug's prompt. Otherwise, any code
|
15
|
+
# creating new threads won't be properly evaluated because new threads will
|
16
|
+
# get blocked by byebug's main thread.
|
17
|
+
#
|
18
|
+
def allowing_other_threads
|
19
|
+
Byebug.unlock
|
20
|
+
res = yield
|
21
|
+
Byebug.lock
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Get current binding and yield it to the given block
|
27
|
+
#
|
9
28
|
def run_with_binding
|
10
29
|
binding = get_binding
|
11
30
|
yield binding
|
12
31
|
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Evaluate +expression+ using +binding+
|
35
|
+
#
|
36
|
+
# @param binding [Binding] Context where to evaluate the expression
|
37
|
+
# @param expression [String] Expression to evaluation
|
38
|
+
# @param stack_on_error [Boolean] Whether to show a stack trace on error.
|
39
|
+
#
|
40
|
+
def eval_with_setting(binding, expression, stack_on_error)
|
41
|
+
allowing_other_threads do
|
42
|
+
if stack_on_error
|
43
|
+
bb_eval(expression, binding)
|
44
|
+
else
|
45
|
+
bb_warning_eval(expression, binding)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
13
49
|
end
|
14
50
|
|
15
51
|
#
|
16
52
|
# Evaluation of expressions from byebug's prompt.
|
17
53
|
#
|
18
54
|
class EvalCommand < Command
|
55
|
+
include EvalFunctions
|
56
|
+
|
19
57
|
self.allow_in_control = true
|
20
58
|
|
21
59
|
def match(input)
|
@@ -24,17 +62,15 @@ module Byebug
|
|
24
62
|
end
|
25
63
|
|
26
64
|
def regexp
|
27
|
-
/^\s*
|
65
|
+
/^\s* e(?:val)? \s+/x
|
28
66
|
end
|
29
67
|
|
30
68
|
def execute
|
31
69
|
expr = @match ? @match.post_match : @input
|
32
70
|
run_with_binding do |b|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
puts "#{bb_warning_eval(expr, b).inspect}"
|
37
|
-
end
|
71
|
+
res = eval_with_setting(b, expr, Setting[:stack_on_error])
|
72
|
+
|
73
|
+
print pr('eval.result', expr: expr, result: res.inspect)
|
38
74
|
end
|
39
75
|
rescue
|
40
76
|
puts "#{$ERROR_INFO.class} Exception: #{$ERROR_INFO.message}"
|
@@ -42,16 +78,18 @@ module Byebug
|
|
42
78
|
|
43
79
|
class << self
|
44
80
|
def names
|
45
|
-
%w(
|
81
|
+
%w(eval)
|
46
82
|
end
|
47
83
|
|
48
84
|
def description
|
49
|
-
|
85
|
+
prettify <<-EOD
|
86
|
+
e[val] <expression>
|
50
87
|
|
51
88
|
Evaluates <expression> and prints its value.
|
52
89
|
|
53
90
|
* NOTE - unknown input is automatically evaluated, to turn this off
|
54
|
-
use 'set noautoeval'.
|
91
|
+
use 'set noautoeval'.
|
92
|
+
EOD
|
55
93
|
end
|
56
94
|
end
|
57
95
|
end
|
@@ -60,6 +98,8 @@ module Byebug
|
|
60
98
|
# Evaluation and pretty printing from byebug's prompt.
|
61
99
|
#
|
62
100
|
class PPCommand < Command
|
101
|
+
include EvalFunctions
|
102
|
+
|
63
103
|
self.allow_in_control = true
|
64
104
|
|
65
105
|
def regexp
|
@@ -86,9 +126,11 @@ module Byebug
|
|
86
126
|
end
|
87
127
|
|
88
128
|
def description
|
89
|
-
|
129
|
+
prettify <<-EOD
|
130
|
+
pp <expression>
|
90
131
|
|
91
|
-
Evaluates <expression> and pretty-prints its value.
|
132
|
+
Evaluates <expression> and pretty-prints its value.
|
133
|
+
EOD
|
92
134
|
end
|
93
135
|
end
|
94
136
|
end
|
@@ -97,26 +139,24 @@ module Byebug
|
|
97
139
|
# Evaluation, pretty printing and columnizing from byebug's prompt.
|
98
140
|
#
|
99
141
|
class PutLCommand < Command
|
142
|
+
include EvalFunctions
|
100
143
|
include Columnize
|
144
|
+
|
101
145
|
self.allow_in_control = true
|
102
146
|
|
103
147
|
def regexp
|
104
|
-
/^\s* putl\s+/x
|
148
|
+
/^\s* putl \s+/x
|
105
149
|
end
|
106
150
|
|
107
151
|
def execute
|
108
152
|
out = StringIO.new
|
109
153
|
run_with_binding do |b|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
end
|
115
|
-
if vals.is_a?(Array)
|
116
|
-
vals = vals.map { |item| item.to_s }
|
117
|
-
puts "#{columnize(vals, Setting[:width])}"
|
154
|
+
res = eval_with_setting(b, @match.post_match, Setting[:stack_on_error])
|
155
|
+
|
156
|
+
if res.is_a?(Array)
|
157
|
+
puts "#{columnize(res.map(&:to_s), Setting[:width])}"
|
118
158
|
else
|
119
|
-
PP.pp(
|
159
|
+
PP.pp(res, out)
|
120
160
|
puts out.string
|
121
161
|
end
|
122
162
|
end
|
@@ -130,9 +170,11 @@ module Byebug
|
|
130
170
|
end
|
131
171
|
|
132
172
|
def description
|
133
|
-
|
173
|
+
prettify <<-EOD
|
174
|
+
putl <expression>
|
134
175
|
|
135
|
-
Evaluates <expression>, an array, and columnize its value.
|
176
|
+
Evaluates <expression>, an array, and columnize its value.
|
177
|
+
EOD
|
136
178
|
end
|
137
179
|
end
|
138
180
|
end
|
@@ -141,26 +183,24 @@ module Byebug
|
|
141
183
|
# Evaluation, pretty printing, columnizing and sorting from byebug's prompt
|
142
184
|
#
|
143
185
|
class PSCommand < Command
|
186
|
+
include EvalFunctions
|
144
187
|
include Columnize
|
188
|
+
|
145
189
|
self.allow_in_control = true
|
146
190
|
|
147
191
|
def regexp
|
148
|
-
/^\s* ps\s+/x
|
192
|
+
/^\s* ps \s+/x
|
149
193
|
end
|
150
194
|
|
151
195
|
def execute
|
152
196
|
out = StringIO.new
|
153
197
|
run_with_binding do |b|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
end
|
159
|
-
if vals.is_a?(Array)
|
160
|
-
vals = vals.map { |item| item.to_s }
|
161
|
-
puts "#{columnize(vals.sort!, Setting[:width])}"
|
198
|
+
res = eval_with_setting(b, @match.post_match, Setting[:stack_on_error])
|
199
|
+
|
200
|
+
if res.is_a?(Array)
|
201
|
+
puts "#{columnize(res.map(&:to_s).sort!, Setting[:width])}"
|
162
202
|
else
|
163
|
-
PP.pp(
|
203
|
+
PP.pp(res, out)
|
164
204
|
puts out.string
|
165
205
|
end
|
166
206
|
end
|
@@ -174,9 +214,11 @@ module Byebug
|
|
174
214
|
end
|
175
215
|
|
176
216
|
def description
|
177
|
-
|
217
|
+
prettify <<-EOD
|
218
|
+
ps <expression>
|
178
219
|
|
179
|
-
Evaluates <expression>, an array, sort and columnize its value.
|
220
|
+
Evaluates <expression>, an array, sort and columnize its value.
|
221
|
+
EOD
|
180
222
|
end
|
181
223
|
end
|
182
224
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
1
3
|
module Byebug
|
2
4
|
#
|
3
5
|
# Implements the finish functionality.
|
@@ -12,7 +14,7 @@ module Byebug
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def execute
|
15
|
-
max_frames =
|
17
|
+
max_frames = @state.context.stack_size - @state.frame
|
16
18
|
if @match[1]
|
17
19
|
n_frames, err = get_int(@match[1], 'finish', 0, max_frames - 1)
|
18
20
|
return errmsg(err) unless n_frames
|
@@ -21,8 +23,8 @@ module Byebug
|
|
21
23
|
end
|
22
24
|
|
23
25
|
force = n_frames == 0 ? true : false
|
24
|
-
@state.context.step_out(@state.
|
25
|
-
@state.
|
26
|
+
@state.context.step_out(@state.frame + n_frames, force)
|
27
|
+
@state.frame = 0
|
26
28
|
@state.proceed
|
27
29
|
end
|
28
30
|
|
@@ -32,11 +34,13 @@ module Byebug
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def description
|
35
|
-
|
37
|
+
prettify <<-EOD
|
38
|
+
fin[ish][ n_frames] Execute until frame returns.
|
36
39
|
|
37
40
|
If no number is given, we run until the current frame returns. If a
|
38
41
|
number of frames `n_frames` is given, then we run until `n_frames`
|
39
|
-
return from the current position.
|
42
|
+
return from the current position.
|
43
|
+
EOD
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
@@ -1,26 +1,28 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
1
3
|
# encoding: utf-8
|
4
|
+
|
5
|
+
require 'pathname'
|
6
|
+
|
2
7
|
module Byebug
|
3
8
|
#
|
4
9
|
# Mixin to assist command parsing
|
5
10
|
#
|
6
11
|
module FrameFunctions
|
7
|
-
def c_frame?(frame_no)
|
8
|
-
@state.context.frame_binding(frame_no).nil?
|
9
|
-
end
|
10
|
-
|
11
12
|
def switch_to_frame(frame_no)
|
12
|
-
frame_no >= 0 ? frame_no :
|
13
|
+
frame_no >= 0 ? frame_no : @state.context.stack_size + frame_no
|
13
14
|
end
|
14
15
|
|
15
16
|
def navigate_to_frame(jump_no)
|
16
17
|
return if jump_no == 0
|
17
|
-
total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.
|
18
|
-
step = jump_no / total_jumps
|
18
|
+
total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame
|
19
|
+
step = jump_no / total_jumps # +1 (up) or -1 (down)
|
20
|
+
|
19
21
|
loop do
|
20
22
|
new_pos += step
|
21
|
-
|
23
|
+
break if new_pos < 0 || new_pos >= @state.context.stack_size
|
22
24
|
|
23
|
-
next if c_frame?(new_pos)
|
25
|
+
next if @state.c_frame?(new_pos)
|
24
26
|
|
25
27
|
current_jumps += 1
|
26
28
|
break if current_jumps == total_jumps
|
@@ -28,126 +30,36 @@ module Byebug
|
|
28
30
|
new_pos
|
29
31
|
end
|
30
32
|
|
31
|
-
def adjust_frame(
|
33
|
+
def adjust_frame(frame, absolute)
|
32
34
|
if absolute
|
33
|
-
|
34
|
-
return errmsg(
|
35
|
+
abs_frame = switch_to_frame(frame)
|
36
|
+
return errmsg(pr('frame.errors.c_frame')) if @state.c_frame?(abs_frame)
|
35
37
|
else
|
36
|
-
|
38
|
+
abs_frame = navigate_to_frame(frame)
|
37
39
|
end
|
38
40
|
|
39
|
-
if
|
40
|
-
return errmsg(
|
41
|
-
elsif
|
42
|
-
return errmsg(
|
41
|
+
if abs_frame >= @state.context.stack_size
|
42
|
+
return errmsg(pr('frame.errors.too_low'))
|
43
|
+
elsif abs_frame < 0
|
44
|
+
return errmsg(pr('frame.errors.too_high'))
|
43
45
|
end
|
44
46
|
|
45
|
-
@state.
|
46
|
-
@state.file = @state.context.frame_file
|
47
|
-
@state.line = @state.context.frame_line
|
47
|
+
@state.frame = abs_frame
|
48
|
+
@state.file = @state.context.frame_file(@state.frame)
|
49
|
+
@state.line = @state.context.frame_line(@state.frame)
|
48
50
|
@state.prev_line = nil
|
49
|
-
ListCommand.new(@state).execute
|
50
|
-
end
|
51
|
-
|
52
|
-
def get_frame_class(style, pos)
|
53
|
-
frame_class = style == 'short' ? '' : "#{@state.context.frame_class pos}"
|
54
|
-
frame_class == '' ? '' : "#{frame_class}."
|
55
|
-
end
|
56
|
-
|
57
|
-
def get_frame_block_and_method(pos)
|
58
|
-
frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/
|
59
|
-
frame_deco_method = "#{@state.context.frame_method pos}"
|
60
|
-
frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2]
|
61
|
-
frame_block_and_method.map { |x| x.nil? ? '' : x }
|
62
|
-
end
|
63
|
-
|
64
|
-
def get_frame_args(style, pos)
|
65
|
-
args = @state.context.frame_args pos
|
66
|
-
return '' if args.empty?
|
67
|
-
|
68
|
-
locals = @state.context.frame_locals pos if style == 'long'
|
69
|
-
my_args = args.map do |arg|
|
70
|
-
case arg[0]
|
71
|
-
when :block
|
72
|
-
prefix, default = '&', 'block'
|
73
|
-
when :rest
|
74
|
-
prefix, default = '*', 'args'
|
75
|
-
else
|
76
|
-
prefix, default = '', nil
|
77
|
-
end
|
78
|
-
|
79
|
-
klass = style == 'long' && arg[1] ? "##{locals[arg[1]].class}" : ''
|
80
|
-
"#{prefix}#{arg[1] || default}#{klass}"
|
81
|
-
end
|
82
|
-
|
83
|
-
"(#{my_args.join(', ')})"
|
84
|
-
end
|
85
|
-
|
86
|
-
def get_frame_call(prefix, pos)
|
87
|
-
frame_block, frame_method = get_frame_block_and_method(pos)
|
88
|
-
frame_class = get_frame_class(Setting[:callstyle], pos)
|
89
|
-
frame_args = get_frame_args(Setting[:callstyle], pos)
|
90
|
-
|
91
|
-
call_str = frame_block + frame_class + frame_method + frame_args
|
92
|
-
|
93
|
-
max_call_str_size = Setting[:width] - prefix.size
|
94
|
-
if call_str.size > max_call_str_size
|
95
|
-
call_str = call_str[0..max_call_str_size - 5] + '...)'
|
96
|
-
end
|
97
|
-
|
98
|
-
call_str
|
99
|
-
end
|
100
|
-
|
101
|
-
def print_backtrace
|
102
|
-
realsize = Context.stack_size
|
103
|
-
calcedsize = @state.context.calced_stack_size
|
104
|
-
if calcedsize != realsize
|
105
|
-
if Byebug.post_mortem?
|
106
|
-
stacksize = calcedsize
|
107
|
-
else
|
108
|
-
errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \
|
109
|
-
"This might be a bug in byebug or ruby's debugging API's\n"
|
110
|
-
stacksize = realsize
|
111
|
-
end
|
112
|
-
else
|
113
|
-
stacksize = calcedsize
|
114
|
-
end
|
115
|
-
(0...stacksize).each do |idx|
|
116
|
-
print_frame(idx)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
require 'pathname'
|
121
|
-
|
122
|
-
def shortpath(fullpath)
|
123
|
-
components = Pathname(fullpath).each_filename.to_a
|
124
|
-
return File.join(components) if components.size <= 2
|
125
51
|
|
126
|
-
|
52
|
+
ListCommand.new(@state).execute if Setting[:autolist]
|
127
53
|
end
|
128
54
|
|
129
|
-
def
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
frame_str = (pos == @state.frame_pos) ? '--> ' : ' '
|
136
|
-
else
|
137
|
-
frame_str = ''
|
138
|
-
end
|
139
|
-
frame_str += c_frame?(pos) ? ' ͱ-- ' : ''
|
140
|
-
|
141
|
-
frame_str += format('#%-2d ', pos)
|
142
|
-
frame_str += get_frame_call frame_str, pos
|
143
|
-
file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}"
|
144
|
-
if frame_str.size + file_line.size + 1 > Setting[:width]
|
145
|
-
frame_str += "\n #{file_line}"
|
146
|
-
else
|
147
|
-
frame_str += " #{file_line}"
|
148
|
-
end
|
55
|
+
def get_pr_arguments(frame_no)
|
56
|
+
file = @state.frame_file(frame_no)
|
57
|
+
line = @state.frame_line(frame_no)
|
58
|
+
call = @state.frame_call(frame_no)
|
59
|
+
mark = @state.frame_mark(frame_no)
|
60
|
+
pos = @state.frame_pos(frame_no)
|
149
61
|
|
150
|
-
|
62
|
+
{ mark: mark, pos: pos, call: call, file: file, line: line }
|
151
63
|
end
|
152
64
|
end
|
153
65
|
|
@@ -155,6 +67,8 @@ module Byebug
|
|
155
67
|
# Show current backtrace.
|
156
68
|
#
|
157
69
|
class WhereCommand < Command
|
70
|
+
include FrameFunctions
|
71
|
+
|
158
72
|
def regexp
|
159
73
|
/^\s* (?:w(?:here)?|bt|backtrace) \s*$/x
|
160
74
|
end
|
@@ -169,22 +83,36 @@ module Byebug
|
|
169
83
|
end
|
170
84
|
|
171
85
|
def description
|
172
|
-
|
86
|
+
prettify <<-EOD
|
87
|
+
w[here]|bt|backtrace Display stack frames.
|
173
88
|
|
174
89
|
Print the entire stack frame. Each frame is numbered; the most recent
|
175
90
|
frame is 0. A frame number can be referred to in the "frame" command;
|
176
91
|
"up" and "down" add or subtract respectively to frame numbers shown.
|
177
92
|
The position of the current frame is marked with -->. C-frames hang
|
178
93
|
from their most immediate Ruby frame to indicate that they are not
|
179
|
-
navigable.
|
94
|
+
navigable.
|
95
|
+
EOD
|
180
96
|
end
|
181
97
|
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def print_backtrace
|
102
|
+
bt = prc('frame.line', (0...@state.context.stack_size)) do |_, index|
|
103
|
+
get_pr_arguments(index)
|
104
|
+
end
|
105
|
+
|
106
|
+
print(bt)
|
107
|
+
end
|
182
108
|
end
|
183
109
|
|
184
110
|
#
|
185
111
|
# Move the current frame up in the backtrace.
|
186
112
|
#
|
187
113
|
class UpCommand < Command
|
114
|
+
include FrameFunctions
|
115
|
+
|
188
116
|
def regexp
|
189
117
|
/^\s* u(?:p)? (?:\s+(\S+))? \s*$/x
|
190
118
|
end
|
@@ -202,7 +130,9 @@ module Byebug
|
|
202
130
|
end
|
203
131
|
|
204
132
|
def description
|
205
|
-
|
133
|
+
prettify <<-EOD
|
134
|
+
up[ count] Move to higher frame.
|
135
|
+
EOD
|
206
136
|
end
|
207
137
|
end
|
208
138
|
end
|
@@ -211,6 +141,8 @@ module Byebug
|
|
211
141
|
# Move the current frame down in the backtrace.
|
212
142
|
#
|
213
143
|
class DownCommand < Command
|
144
|
+
include FrameFunctions
|
145
|
+
|
214
146
|
def regexp
|
215
147
|
/^\s* down (?:\s+(\S+))? \s*$/x
|
216
148
|
end
|
@@ -228,7 +160,9 @@ module Byebug
|
|
228
160
|
end
|
229
161
|
|
230
162
|
def description
|
231
|
-
|
163
|
+
prettify <<-EOD
|
164
|
+
down[ count] Move to lower frame.
|
165
|
+
EOD
|
232
166
|
end
|
233
167
|
end
|
234
168
|
end
|
@@ -237,12 +171,17 @@ module Byebug
|
|
237
171
|
# Move to specific frames in the backtrace.
|
238
172
|
#
|
239
173
|
class FrameCommand < Command
|
174
|
+
include FrameFunctions
|
175
|
+
|
240
176
|
def regexp
|
241
177
|
/^\s* f(?:rame)? (?:\s+(\S+))? \s*$/x
|
242
178
|
end
|
243
179
|
|
244
180
|
def execute
|
245
|
-
|
181
|
+
unless @match[1]
|
182
|
+
print(pr('frame.line', get_pr_arguments(@state.frame)))
|
183
|
+
return
|
184
|
+
end
|
246
185
|
|
247
186
|
pos, err = get_int(@match[1], 'Frame')
|
248
187
|
return errmsg(err) unless pos
|
@@ -256,7 +195,8 @@ module Byebug
|
|
256
195
|
end
|
257
196
|
|
258
197
|
def description
|
259
|
-
|
198
|
+
prettify <<-EOD
|
199
|
+
f[rame][ frame-number]
|
260
200
|
|
261
201
|
Move the current frame to the specified frame number, or the 0 if no
|
262
202
|
frame-number has been given.
|
@@ -267,7 +207,8 @@ module Byebug
|
|
267
207
|
|
268
208
|
Without an argument, the command prints the current stack frame. Since
|
269
209
|
the current position is redisplayed, it may trigger a resyncronization
|
270
|
-
if there is a front end also watching over things.
|
210
|
+
if there is a front end also watching over things.
|
211
|
+
EOD
|
271
212
|
end
|
272
213
|
end
|
273
214
|
end
|