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