byebug 1.6.1 → 1.7.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 +8 -1
- data/GUIDE.md +34 -14
- data/ext/byebug/context.c +0 -1
- data/lib/byebug/commands/frame.rb +71 -33
- data/lib/byebug/commands/info.rb +18 -18
- data/lib/byebug/commands/set.rb +2 -2
- data/lib/byebug/context.rb +22 -2
- data/lib/byebug/processor.rb +20 -21
- data/lib/byebug/version.rb +1 -1
- data/test/breakpoints_test.rb +3 -4
- data/test/examples/breakpoint.rb +1 -1
- data/test/examples/breakpoint2.rb +2 -2
- data/test/examples/finish.rb +2 -2
- data/test/examples/frame.rb +10 -2
- data/test/examples/frame_deep.rb +2 -2
- data/test/examples/info.rb +4 -4
- data/test/examples/jump.rb +2 -2
- data/test/examples/method.rb +2 -2
- data/test/frame_test.rb +141 -104
- data/test/info_test.rb +5 -5
- data/test/method_test.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 489c114f27cc5006d198149fccf0ff0e6390cd2a
|
4
|
+
data.tar.gz: be024abb6bfc9d9f989e29e9f97da9cdca1a1daf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da63414df26b9564f6818645b1451f8780fcb324c7b30916675841b053fbfee0070f3e6c0a7d420e21fff5c07a0dd8a7c20b99cf1ed4dbba869d84c4089ea957
|
7
|
+
data.tar.gz: 4f5c740d9b6ea6e41115b43e982a2a1b1fc28b4c0baefa12ce0c796d005cd23e07df3fc5f43f539a9edc790385a7e4978e06d1dcf065c81f3210c6cc0fa6e37c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 1.7.0
|
2
|
+
|
3
|
+
* Callstack display: specifically mark c-frames
|
4
|
+
* Callstack navigation: skip c-frames
|
5
|
+
* Callstack navigation: autolist after navigation commands
|
6
|
+
|
7
|
+
|
1
8
|
## 1.6.1
|
2
9
|
|
3
10
|
* Windows compatibiliy: compilation and terminal width issues
|
@@ -16,7 +23,7 @@
|
|
16
23
|
* No more Byebug.start to get correct callstack information! Dropping `byebug`
|
17
24
|
anywhere and inmediately printing the stack just works now. :)
|
18
25
|
|
19
|
-
|
26
|
+
|
20
27
|
## 1.4.2
|
21
28
|
|
22
29
|
* Fixes crash when using "help command subcommand"
|
data/GUIDE.md
CHANGED
@@ -188,12 +188,12 @@ resumes execution. Notice the difference between `display a` and
|
|
188
188
|
after it is evaluated. To remove a display expression `undisplay` is used. If we
|
189
189
|
give a display number, just that display expression is removed.
|
190
190
|
|
191
|
-
We also used a new command `where`(see [backtrace]()) to show the
|
191
|
+
We also used a new command `where`(see [backtrace]()) to show the callstack. In
|
192
192
|
the above situation, starting from the bottom line we see we called the `hanoi`
|
193
193
|
method from line 34 of the file `hanoi.rb` and the `hanoi` method called itself
|
194
194
|
two more times at line 4.
|
195
195
|
|
196
|
-
In the
|
196
|
+
In the callstack we show a _current frame_ mark, the frame number, the method
|
197
197
|
being called, the names of the parameters, the types those parameters
|
198
198
|
_currently_ have and the file-line position. Remember it's possible that when
|
199
199
|
the program was called the parameters had different types, since the types of
|
@@ -205,16 +205,36 @@ Now let's move around the callstack.
|
|
205
205
|
```bash
|
206
206
|
(byebug) undisplay
|
207
207
|
Clear all expressions? (y/n) y
|
208
|
-
(byebug
|
208
|
+
(byebug) i_args
|
209
209
|
NameError Exception: undefined local variable or method `i_args' for main:Object
|
210
|
-
(byebug
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
210
|
+
(byebug) frame -1
|
211
|
+
[25, 34] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
|
212
|
+
25: exit 2
|
213
|
+
26: end
|
214
|
+
27: end
|
215
|
+
28:
|
216
|
+
29: if n < 1 or n > 100
|
217
|
+
30: puts "*** number of disks should be between 1 and 100"
|
218
|
+
31: exit 2
|
219
|
+
32: end
|
220
|
+
33:
|
221
|
+
=> 34: hanoi(n, :a, :b, :c)
|
222
|
+
(byebug) i_args
|
223
|
+
0
|
224
|
+
(byebug) p n
|
215
225
|
3
|
216
|
-
(byebug
|
217
|
-
|
226
|
+
(byebug) down 2
|
227
|
+
[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb
|
228
|
+
1: # Solves the classic Towers of Hanoi puzzle.
|
229
|
+
2: def hanoi(n,a,b,c)
|
230
|
+
3: if n-1 > 0
|
231
|
+
=> 4: hanoi(n-1, a, c, b)
|
232
|
+
5: end
|
233
|
+
6: puts "Move disk %s to %s" % [a, b]
|
234
|
+
7: if n-1 > 0
|
235
|
+
8: hanoi(n-1, c, b, a)
|
236
|
+
9: end
|
237
|
+
10: end
|
218
238
|
(byebug:1) p n
|
219
239
|
2
|
220
240
|
```
|
@@ -325,15 +345,15 @@ Displaying frame's full file names is off.
|
|
325
345
|
--> #0 TestTri.test_basic at test-triangle.rb:7
|
326
346
|
#1 MiniTest::Unit::TestCase.run(runner#MiniTest::Unit) at .../2.0.0/minitest/unit.rb:1301
|
327
347
|
#2 MiniTest::Unit.block in _run_suite(suite#Class, type#Symbol) at .../2.0.0/minitest/unit.rb:919
|
328
|
-
|
348
|
+
+-- #3 Array.map at .../2.0.0/minitest/unit.rb:912
|
329
349
|
#4 MiniTest::Unit._run_suite(suite#Class, type#Symbol) at .../2.0.0/minitest/unit.rb:912
|
330
350
|
#5 MiniTest::Unit.block in _run_suites(suites#Array, type#Symbol) at .../2.0.0/minitest/unit.rb:899
|
331
|
-
|
351
|
+
+-- #6 Array.map at .../2.0.0/minitest/unit.rb:899
|
332
352
|
#7 MiniTest::Unit._run_suites(suites#Array, type#Symbol) at .../2.0.0/minitest/unit.rb:899
|
333
353
|
#8 MiniTest::Unit._run_anything(type#Symbol) at .../2.0.0/minitest/unit.rb:867
|
334
354
|
#9 MiniTest::Unit.run_tests at .../2.0.0/minitest/unit.rb:1060
|
335
355
|
#10 MiniTest::Unit.block in _run(args#Array) at .../2.0.0/minitest/unit.rb:1047
|
336
|
-
|
356
|
+
+-- #11 Array.each at .../2.0.0/minitest/unit.rb:1046
|
337
357
|
#12 MiniTest::Unit._run(args#Array) at .../2.0.0/minitest/unit.rb:1046
|
338
358
|
#13 MiniTest::Unit.run(args#Array) at .../2.0.0/minitest/unit.rb:1035
|
339
359
|
#14 #<Class:MiniTest::Unit>.block in autorun at .../2.0.0/minitest/unit.rb:789
|
@@ -565,7 +585,7 @@ options and descriptions, use the `--help` option.
|
|
565
585
|
|
566
586
|
```bash
|
567
587
|
$ byebug --help
|
568
|
-
byebug 1.
|
588
|
+
byebug 1.6.1
|
569
589
|
Usage: byebug [options] <script.rb> -- <script.rb parameters>
|
570
590
|
|
571
591
|
Options:
|
data/ext/byebug/context.c
CHANGED
@@ -3,25 +3,48 @@ module Byebug
|
|
3
3
|
# Mix-in module to assist in command parsing.
|
4
4
|
module FrameFunctions
|
5
5
|
|
6
|
-
def
|
7
|
-
@state.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
6
|
+
def c_frame?(frame_no)
|
7
|
+
@state.context.frame_binding(frame_no).nil?
|
8
|
+
end
|
9
|
+
|
10
|
+
def switch_to_frame(frame_no)
|
11
|
+
if frame_no < 0
|
12
|
+
abs_frame_no = @state.context.stack_size + frame_no
|
14
13
|
else
|
15
|
-
|
14
|
+
abs_frame_no = frame_no
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def navigate_to_frame(jump_no)
|
19
|
+
return if jump_no == 0
|
20
|
+
total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos
|
21
|
+
step = jump_no/total_jumps
|
22
|
+
loop do
|
23
|
+
new_pos += step
|
24
|
+
return new_pos if new_pos < 0 || new_pos >= @state.context.stack_size
|
25
|
+
|
26
|
+
next if c_frame?(new_pos)
|
27
|
+
|
28
|
+
current_jumps += 1
|
29
|
+
break if current_jumps == total_jumps
|
16
30
|
end
|
31
|
+
return new_pos
|
32
|
+
end
|
17
33
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
return errmsg "
|
34
|
+
def adjust_frame(frame_pos, absolute)
|
35
|
+
if absolute
|
36
|
+
abs_frame_pos = switch_to_frame(frame_pos)
|
37
|
+
return errmsg "Can't navigate to c-frame\n" if c_frame?(abs_frame_pos)
|
38
|
+
else
|
39
|
+
abs_frame_pos = navigate_to_frame(frame_pos)
|
22
40
|
end
|
23
41
|
|
24
|
-
|
42
|
+
return errmsg "Can't navigate beyond the oldest frame\n" if
|
43
|
+
abs_frame_pos >= @state.context.stack_size
|
44
|
+
return errmsg "Can't navigate beyond the newest frame\n" if
|
45
|
+
abs_frame_pos < 0
|
46
|
+
|
47
|
+
if @state.frame_pos != abs_frame_pos
|
25
48
|
@state.previous_line = nil
|
26
49
|
@state.frame_pos = abs_frame_pos
|
27
50
|
end
|
@@ -29,7 +52,7 @@ module Byebug
|
|
29
52
|
@state.file = @state.context.frame_file @state.frame_pos
|
30
53
|
@state.line = @state.context.frame_line @state.frame_pos
|
31
54
|
|
32
|
-
|
55
|
+
ListCommand.new(@state).execute
|
33
56
|
end
|
34
57
|
|
35
58
|
def get_frame_class(style, pos)
|
@@ -37,25 +60,40 @@ module Byebug
|
|
37
60
|
return frame_class == '' ? '' : "#{frame_class}."
|
38
61
|
end
|
39
62
|
|
63
|
+
def get_frame_block_and_method(pos)
|
64
|
+
frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/
|
65
|
+
frame_deco_method = "#{@state.context.frame_method pos}"
|
66
|
+
frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2]
|
67
|
+
return frame_block_and_method.map{ |x| x.nil? ? '' : x }
|
68
|
+
end
|
69
|
+
|
40
70
|
def get_frame_args(style, pos)
|
41
71
|
args = @state.context.frame_args pos
|
42
|
-
if args
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
72
|
+
return '' if args.empty?
|
73
|
+
|
74
|
+
locals = @state.context.frame_locals pos if style == :long
|
75
|
+
my_args = args.map do |arg|
|
76
|
+
case arg[0]
|
77
|
+
when :block
|
78
|
+
prefix, default = '&', 'block'
|
79
|
+
when :rest
|
80
|
+
prefix, default = '*', 'args'
|
81
|
+
else
|
82
|
+
prefix, default = '', nil
|
83
|
+
end
|
84
|
+
klass = style == :long && arg[1] ? "##{locals[arg[1]].class}" : ''
|
85
|
+
"#{prefix}#{arg[1] || default}#{klass}"
|
49
86
|
end
|
50
|
-
|
87
|
+
|
88
|
+
return "(#{my_args.join(', ')})"
|
51
89
|
end
|
52
90
|
|
53
91
|
def get_frame_call(prefix, pos)
|
92
|
+
frame_block, frame_method = get_frame_block_and_method(pos)
|
54
93
|
frame_class = get_frame_class(Command.settings[:callstyle], pos)
|
55
|
-
frame_method = "#{@state.context.frame_method pos}"
|
56
94
|
frame_args = get_frame_args(Command.settings[:callstyle], pos)
|
57
95
|
|
58
|
-
call_str = frame_class + frame_method + frame_args
|
96
|
+
call_str = frame_block + frame_class + frame_method + frame_args
|
59
97
|
|
60
98
|
max_call_str_size = Command.settings[:width] - prefix.size
|
61
99
|
if call_str.size > max_call_str_size
|
@@ -84,10 +122,11 @@ module Byebug
|
|
84
122
|
end
|
85
123
|
|
86
124
|
if mark_current
|
87
|
-
frame_str = (pos == @state.frame_pos) ?
|
125
|
+
frame_str = (pos == @state.frame_pos) ? '--> ' : ' '
|
88
126
|
else
|
89
127
|
frame_str = ""
|
90
128
|
end
|
129
|
+
frame_str += c_frame?(pos) ? ' ͱ-- ' : ''
|
91
130
|
|
92
131
|
frame_str += sprintf "#%-2d ", pos
|
93
132
|
frame_str += get_frame_call frame_str, pos
|
@@ -121,9 +160,11 @@ module Byebug
|
|
121
160
|
%{w[here]|bt|backtrace\tdisplay stack frames
|
122
161
|
|
123
162
|
Print the entire stack frame. Each frame is numbered, the most recent
|
124
|
-
frame is 0.
|
163
|
+
frame is 0. Frame number can be referred to in the "frame" command;
|
125
164
|
"up" and "down" add or subtract respectively to frame numbers shown.
|
126
|
-
The position of the current frame is marked with -->.
|
165
|
+
The position of the current frame is marked with -->. C-frames hang
|
166
|
+
from their most inmediate ruby frame to indicate that they are not
|
167
|
+
navigable}
|
127
168
|
end
|
128
169
|
end
|
129
170
|
end
|
@@ -181,11 +222,8 @@ module Byebug
|
|
181
222
|
end
|
182
223
|
|
183
224
|
def execute
|
184
|
-
|
185
|
-
|
186
|
-
else
|
187
|
-
return unless pos = get_int(@match[1], "Frame")
|
188
|
-
end
|
225
|
+
return print_frame @state.frame_pos unless @match[1]
|
226
|
+
return unless pos = get_int(@match[1], "Frame")
|
189
227
|
adjust_frame(pos, true)
|
190
228
|
end
|
191
229
|
|
data/lib/byebug/commands/info.rb
CHANGED
@@ -139,8 +139,9 @@ module Byebug
|
|
139
139
|
end
|
140
140
|
|
141
141
|
def info_file_path(file)
|
142
|
+
print "File #{file}"
|
142
143
|
path = LineCache.path(file)
|
143
|
-
print " - #{path}" if path and path != file
|
144
|
+
print " - #{path}\n" if path and path != file
|
144
145
|
end
|
145
146
|
private :info_file_path
|
146
147
|
|
@@ -173,35 +174,34 @@ module Byebug
|
|
173
174
|
def info_file(*args)
|
174
175
|
return info_files unless args[0]
|
175
176
|
|
176
|
-
|
177
|
-
|
178
|
-
subcmd = Command.find(InfoFileSubcommands, param)
|
179
|
-
return errmsg "Invalid parameter #{param}\n" unless subcmd
|
177
|
+
subcmd = Command.find(InfoFileSubcommands, args[1] || 'basic')
|
178
|
+
return errmsg "Invalid parameter #{args[1]}\n" unless subcmd
|
180
179
|
|
181
180
|
unless LineCache::cached?(args[0])
|
182
|
-
|
183
|
-
|
184
|
-
end
|
181
|
+
return print "File #{args[0]} is not cached\n" unless
|
182
|
+
LineCache::cached_script?(args[0])
|
185
183
|
LineCache::cache(args[0], Command.settings[:autoreload])
|
186
184
|
end
|
187
185
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
186
|
+
if %w(all basic).member?(subcmd.name)
|
187
|
+
info_file_path(args[0])
|
188
|
+
info_file_lines(args[0])
|
189
|
+
if subcmd.name == 'all'
|
190
|
+
info_file_breakpoints(args[0])
|
191
|
+
info_file_mtime(args[0])
|
192
|
+
info_file_sha1(args[0])
|
193
|
+
end
|
194
|
+
else
|
195
|
+
print "File #{args[0]}\n" if subcmd.name != 'path'
|
196
|
+
send("info_file_#{subcmd.name}", args[0])
|
197
|
+
end
|
196
198
|
end
|
197
199
|
|
198
200
|
def info_files(*args)
|
199
201
|
files = LineCache::cached_files
|
200
202
|
files += SCRIPT_LINES__.keys unless 'stat' == args[0]
|
201
203
|
files.uniq.sort.each do |file|
|
202
|
-
print "File #{file}"
|
203
204
|
info_file_path(file)
|
204
|
-
print "\n"
|
205
205
|
info_file_mtime(file)
|
206
206
|
end
|
207
207
|
end
|
data/lib/byebug/commands/set.rb
CHANGED
@@ -94,8 +94,8 @@ module Byebug
|
|
94
94
|
when /^basename$/
|
95
95
|
Command.settings[:basename] = set_on
|
96
96
|
when /^callstyle$/
|
97
|
-
if args[0] and (args[0] == 'short' or
|
98
|
-
Command.settings[:callstyle] =
|
97
|
+
if args[0] and (args[0] == 'short' or args[0] == 'long')
|
98
|
+
Command.settings[:callstyle] = args[0].to_sym
|
99
99
|
else
|
100
100
|
print "Invalid callstyle. Should be one of: \"short\" or \"long\"\n"
|
101
101
|
end
|
data/lib/byebug/context.rb
CHANGED
@@ -13,10 +13,30 @@ module Byebug
|
|
13
13
|
eval "local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}", bind
|
14
14
|
end
|
15
15
|
|
16
|
+
def c_frame_args frame_no
|
17
|
+
myself = frame_self frame_no
|
18
|
+
return [] unless myself.to_s != 'main'
|
19
|
+
myself.send(:method, frame_method(frame_no)).parameters
|
20
|
+
end
|
21
|
+
|
22
|
+
def ruby_frame_args bind
|
23
|
+
return [] unless eval '__method__', bind
|
24
|
+
begin
|
25
|
+
eval "self.method(__method__).parameters", bind
|
26
|
+
rescue NameError => e
|
27
|
+
print "WARNING: Got exception #{e.class}: \"#{e.message}\" " \
|
28
|
+
"while retreving parameters from frame\n"
|
29
|
+
return []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
16
33
|
def frame_args frame_no = 0
|
17
34
|
bind = frame_binding frame_no
|
18
|
-
|
19
|
-
|
35
|
+
if bind.nil?
|
36
|
+
c_frame_args frame_no
|
37
|
+
else
|
38
|
+
ruby_frame_args bind
|
39
|
+
end
|
20
40
|
end
|
21
41
|
|
22
42
|
def handler
|
data/lib/byebug/processor.rb
CHANGED
@@ -46,12 +46,12 @@ module Byebug
|
|
46
46
|
@display = []
|
47
47
|
|
48
48
|
@mutex = Mutex.new
|
49
|
-
@last_cmd
|
50
|
-
@last_file
|
51
|
-
@last_line
|
52
|
-
@
|
53
|
-
@
|
54
|
-
@
|
49
|
+
@last_cmd = nil # To allow empty (just <RET>) commands
|
50
|
+
@last_file = nil # Filename the last time we stopped
|
51
|
+
@last_line = nil # line number the last time we stopped
|
52
|
+
@breakpoints_were_empty = false # Show breakpoints 1st time
|
53
|
+
@displays_were_empty = true # No display 1st time
|
54
|
+
@context_was_dead = true # Assume we haven't started.
|
55
55
|
end
|
56
56
|
|
57
57
|
def interface=(interface)
|
@@ -278,12 +278,11 @@ module Byebug
|
|
278
278
|
end
|
279
279
|
|
280
280
|
def preloop(commands, context)
|
281
|
-
@
|
282
|
-
@byebug_context_was_dead
|
281
|
+
@context_was_dead = true if context.dead? and not @context_was_dead
|
283
282
|
|
284
283
|
if Byebug.annotate.to_i > 2
|
285
284
|
aprint('stopped')
|
286
|
-
if @
|
285
|
+
if @context_was_dead
|
287
286
|
aprint('exited')
|
288
287
|
print "The program finished.\n"
|
289
288
|
end
|
@@ -309,7 +308,7 @@ module Byebug
|
|
309
308
|
end
|
310
309
|
if not context.dead? and @@Show_annotations_run.find{|pat| cmd =~ pat}
|
311
310
|
aprint 'starting'
|
312
|
-
@
|
311
|
+
@context_was_dead = false
|
313
312
|
end
|
314
313
|
end
|
315
314
|
end
|
@@ -323,23 +322,23 @@ module Byebug
|
|
323
322
|
end
|
324
323
|
|
325
324
|
def breakpoint_annotations(commands, context)
|
326
|
-
unless Byebug.breakpoints.empty? and @
|
325
|
+
unless Byebug.breakpoints.empty? and @breakpoints_were_empty
|
327
326
|
annotation('breakpoints', commands, context, "info breakpoints")
|
328
|
-
@
|
327
|
+
@breakpoints_were_empty = Byebug.breakpoints.empty?
|
329
328
|
end
|
330
329
|
end
|
331
330
|
|
332
331
|
def display_annotations(commands, context)
|
333
332
|
return if display.empty?
|
334
|
-
|
335
|
-
|
336
|
-
|
333
|
+
have_display = display.find{|d| d[0]}
|
334
|
+
return unless have_display and @displays_were_empty
|
335
|
+
@displays_were_empty = have_display
|
337
336
|
annotation('display', commands, context, "display")
|
338
337
|
end
|
339
338
|
|
340
339
|
class State
|
341
|
-
attr_accessor :commands, :context, :display, :file
|
342
|
-
attr_accessor :
|
340
|
+
attr_accessor :commands, :context, :display, :file, :frame_pos
|
341
|
+
attr_accessor :interface, :line, :previous_line
|
343
342
|
|
344
343
|
def initialize(commands, context, display, file, interface, line)
|
345
344
|
@commands, @context, @display = commands, context, display
|
@@ -367,7 +366,7 @@ module Byebug
|
|
367
366
|
def initialize(interface)
|
368
367
|
super()
|
369
368
|
@interface = interface
|
370
|
-
@
|
369
|
+
@context_was_dead = true # Assume we haven't started.
|
371
370
|
end
|
372
371
|
|
373
372
|
def process_commands(verbose=false)
|
@@ -377,12 +376,12 @@ module Byebug
|
|
377
376
|
state = State.new(@interface, control_cmds)
|
378
377
|
commands = control_cmds.map{|cmd| cmd.new(state) }
|
379
378
|
|
380
|
-
unless @
|
379
|
+
unless @context_was_dead
|
381
380
|
if Byebug.annotate.to_i > 2
|
382
381
|
aprint 'exited'
|
383
382
|
print "The program finished.\n"
|
384
383
|
end
|
385
|
-
@
|
384
|
+
@context_was_dead = true
|
386
385
|
end
|
387
386
|
|
388
387
|
while input = @interface.read_command(prompt(nil))
|
@@ -407,7 +406,7 @@ module Byebug
|
|
407
406
|
# Note: have an unused 'context' parameter to match the local interface.
|
408
407
|
def prompt(context)
|
409
408
|
p = '(byebug:ctrl) '
|
410
|
-
p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if
|
409
|
+
p = afmt("pre-prompt") + p + "\n" + afmt("prompt") if
|
411
410
|
Byebug.annotate.to_i > 2
|
412
411
|
return p
|
413
412
|
end
|
data/lib/byebug/version.rb
CHANGED
data/test/breakpoints_test.rb
CHANGED
@@ -71,8 +71,7 @@ class TestBreakpoints < TestDsl::TestCase
|
|
71
71
|
|
72
72
|
it 'must stop at the correct file' do
|
73
73
|
enter 'break 14', 'cont'
|
74
|
-
debug_file('breakpoint') {
|
75
|
-
$state.file.must_equal fullpath('breakpoint') }
|
74
|
+
debug_file('breakpoint') { $state.file.must_equal fullpath('breakpoint') }
|
76
75
|
end
|
77
76
|
|
78
77
|
describe 'show a message' do
|
@@ -161,7 +160,7 @@ class TestBreakpoints < TestDsl::TestCase
|
|
161
160
|
|
162
161
|
describe 'set breakpoint to a method' do
|
163
162
|
describe 'set breakpoint to an instance method' do
|
164
|
-
before { enter 'break
|
163
|
+
before { enter 'break BreakpointExample#b', 'cont' }
|
165
164
|
|
166
165
|
it 'must stop at the correct line' do
|
167
166
|
debug_file('breakpoint') { $state.line.must_equal 5 }
|
@@ -174,7 +173,7 @@ class TestBreakpoints < TestDsl::TestCase
|
|
174
173
|
end
|
175
174
|
|
176
175
|
describe 'set breakpoint to a class method' do
|
177
|
-
before { enter 'break
|
176
|
+
before { enter 'break BreakpointExample.a', 'cont' }
|
178
177
|
|
179
178
|
it 'must stop at the correct line' do
|
180
179
|
debug_file('breakpoint') { $state.line.must_equal 2 }
|
data/test/examples/breakpoint.rb
CHANGED
data/test/examples/finish.rb
CHANGED
data/test/examples/frame.rb
CHANGED
@@ -1,20 +1,28 @@
|
|
1
1
|
byebug
|
2
2
|
|
3
|
-
class
|
3
|
+
class FrameExample
|
4
|
+
def initialize(f)
|
5
|
+
@f = f
|
6
|
+
end
|
7
|
+
|
4
8
|
def a
|
5
9
|
b
|
6
10
|
end
|
11
|
+
|
7
12
|
def b
|
8
13
|
c
|
9
14
|
2
|
10
15
|
end
|
16
|
+
|
11
17
|
def c
|
12
18
|
d('a')
|
13
19
|
3
|
14
20
|
end
|
21
|
+
|
15
22
|
def d(e)
|
16
23
|
5
|
17
24
|
end
|
18
25
|
end
|
19
26
|
|
20
|
-
|
27
|
+
local_var = "hola"
|
28
|
+
FrameExample.new('f').a
|
data/test/examples/frame_deep.rb
CHANGED
data/test/examples/info.rb
CHANGED
@@ -9,7 +9,7 @@ z = 8
|
|
9
9
|
z = 9
|
10
10
|
bla("a" * 30, "b")
|
11
11
|
|
12
|
-
class
|
12
|
+
class InfoExample
|
13
13
|
def initialize
|
14
14
|
@foo = "bar"
|
15
15
|
@bla = "blabla"
|
@@ -33,6 +33,6 @@ class A
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
InfoExample.new.b
|
37
|
+
InfoExample.new.a
|
38
|
+
InfoExample.new.c
|
data/test/examples/jump.rb
CHANGED
data/test/examples/method.rb
CHANGED
data/test/frame_test.rb
CHANGED
@@ -1,76 +1,142 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
3
|
class TestFrame < TestDsl::TestCase
|
4
|
+
describe 'when byebug started at the beginning' do
|
5
|
+
before do
|
6
|
+
@tst_file = fullpath('frame')
|
7
|
+
enter 'break 23', 'cont'
|
8
|
+
end
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
10
|
+
it 'must go up' do
|
11
|
+
enter 'up'
|
12
|
+
debug_file('frame') { $state.line.must_equal 18 }
|
13
|
+
end
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
it 'must go up by specific number of frames' do
|
16
|
+
enter 'up 2'
|
17
|
+
debug_file('frame') { $state.line.must_equal 13 }
|
18
|
+
end
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
it 'must go down' do
|
21
|
+
enter 'up', 'down'
|
22
|
+
debug_file('frame') { $state.line.must_equal 23 }
|
23
|
+
end
|
19
24
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
it 'must go down by specific number of frames' do
|
26
|
+
enter 'up 3', 'down 2'
|
27
|
+
debug_file('frame') { $state.line.must_equal 18 }
|
28
|
+
end
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
it 'must set frame' do
|
31
|
+
enter 'frame 2'
|
32
|
+
debug_file('frame') { $state.line.must_equal 13 }
|
33
|
+
end
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
it 'must print current stack frame when without arguments' do
|
36
|
+
enter 'up', 'frame'
|
37
|
+
debug_file('frame')
|
38
|
+
check_output_includes /#1 FrameExample\.c\s+at #{@tst_file}:18/
|
39
|
+
end
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
41
|
+
it 'must set frame to the first one' do
|
42
|
+
enter 'up', 'frame 0'
|
43
|
+
debug_file('frame') { $state.line.must_equal 23 }
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
46
|
+
it 'must set frame to the last one' do
|
47
|
+
enter 'bt', 'frame -1'
|
48
|
+
debug_file('frame') { $state.file.must_match /minitest\/unit.rb/ }
|
49
|
+
check_output_doesnt_include "at #{@tst_file}:"
|
50
|
+
end
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
it 'must not set frame if the frame number is too low' do
|
53
|
+
enter 'down'
|
54
|
+
debug_file('frame') { $state.line.must_equal 23 }
|
55
|
+
check_output_includes \
|
56
|
+
"Can't navigate beyond the newest frame", interface.error_queue
|
57
|
+
end
|
51
58
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
it 'must not set frame if the frame number is too high' do
|
60
|
+
enter 'up 100'
|
61
|
+
debug_file('frame') { $state.line.must_equal 23 }
|
62
|
+
check_output_includes \
|
63
|
+
"Can't navigate beyond the oldest frame", interface.error_queue
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'fullpath' do
|
67
|
+
def short_path(fullpath)
|
68
|
+
separator = File::ALT_SEPARATOR || File::SEPARATOR
|
69
|
+
"...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
|
70
|
+
end
|
58
71
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
72
|
+
describe 'when set' do
|
73
|
+
temporary_change_hash Byebug::Command.settings, :frame_fullpath, true
|
74
|
+
|
75
|
+
it 'must display current backtrace with fullpaths' do
|
76
|
+
enter 'where'
|
77
|
+
debug_file 'frame'
|
78
|
+
check_output_includes \
|
79
|
+
/--> #0 FrameExample\.d\(e#String\)\s+at #{@tst_file}:23/,
|
80
|
+
/#1 FrameExample\.c\s+at #{@tst_file}:18/,
|
81
|
+
/#2 FrameExample\.b\s+at #{@tst_file}:13/
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'when unset' do
|
86
|
+
temporary_change_hash Byebug::Command.settings, :frame_fullpath, false
|
87
|
+
|
88
|
+
it 'must display current backtrace with shortpaths' do
|
89
|
+
enter 'where'
|
90
|
+
debug_file 'frame'
|
91
|
+
check_output_includes \
|
92
|
+
/--> #0 FrameExample\.d\(e#String\)\s+at #{short_path(@tst_file)}:23/,
|
93
|
+
/#1 FrameExample\.c\s+at #{short_path(@tst_file)}:18/,
|
94
|
+
/#2 FrameExample\.b\s+at #{short_path(@tst_file)}:13/,
|
95
|
+
/#3 FrameExample\.a\s+at #{short_path(@tst_file)}:9/
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'callstyle' do
|
101
|
+
describe 'long' do
|
102
|
+
temporary_change_hash Byebug::Command.settings, :callstyle, :long
|
103
|
+
|
104
|
+
it 'displays current backtrace with callstyle "long"' do
|
105
|
+
enter 'where'
|
106
|
+
debug_file 'frame'
|
107
|
+
check_output_includes \
|
108
|
+
/--> #0 FrameExample\.d\(e#String\)\s+at #{@tst_file}:23/,
|
109
|
+
/#1 FrameExample\.c\s+at #{@tst_file}:18/,
|
110
|
+
/#2 FrameExample\.b\s+at #{@tst_file}:13/,
|
111
|
+
/#3 FrameExample\.a\s+at #{@tst_file}:9/
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'short' do
|
116
|
+
temporary_change_hash Byebug::Command.settings, :callstyle, :short
|
117
|
+
|
118
|
+
it 'displays current backtrace with callstyle "short"' do
|
119
|
+
enter 'where'
|
120
|
+
debug_file 'frame'
|
121
|
+
check_output_includes /--> #0 d\(e\)\s+at #{@tst_file}:23/,
|
122
|
+
/#1 c\s+at #{@tst_file}:18/,
|
123
|
+
/#2 b\s+at #{@tst_file}:13/,
|
124
|
+
/#3 a\s+at #{@tst_file}:9/
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
64
128
|
end
|
65
129
|
|
66
130
|
describe 'when byebug is started deep in the callstack' do
|
131
|
+
before { @tst_file = fullpath('frame_deep') }
|
132
|
+
|
67
133
|
it 'must print backtrace' do
|
68
134
|
enter 'break 16', 'cont', 'where'
|
69
135
|
debug_file 'frame_deep'
|
70
136
|
check_output_includes \
|
71
|
-
/--> #0
|
72
|
-
/#1
|
73
|
-
/#2
|
137
|
+
/--> #0 FrameDeepExample\.d\(e#String\)\s+at #{@tst_file}:16/,
|
138
|
+
/#1 FrameDeepExample\.c\s+at #{@tst_file}:13/,
|
139
|
+
/#2 FrameDeepExample\.b\s+at #{@tst_file}:8/
|
74
140
|
end
|
75
141
|
|
76
142
|
it 'must go up' do
|
@@ -95,65 +161,37 @@ class TestFrame < TestDsl::TestCase
|
|
95
161
|
end
|
96
162
|
end
|
97
163
|
|
98
|
-
describe '
|
99
|
-
|
100
|
-
|
101
|
-
|
164
|
+
describe 'c-frames (issue #10)' do
|
165
|
+
before do
|
166
|
+
@tst_file = fullpath('frame')
|
167
|
+
enter 'break 5', 'cont'
|
102
168
|
end
|
103
169
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
/--> #0 A.d(e#String) at #{fullpath('frame')}:16/x,
|
112
|
-
/#1 A.c at #{fullpath('frame')}:12/x,
|
113
|
-
/#2 A.b at #{fullpath('frame')}:8/x
|
114
|
-
end
|
170
|
+
it 'must mark c-frames when printing the stack' do
|
171
|
+
enter 'where'
|
172
|
+
debug_file 'frame'
|
173
|
+
check_output_includes \
|
174
|
+
/--> #0 FrameExample.initialize\(f#String\)\s+at #{@tst_file}:5/,
|
175
|
+
/ͱ-- #1 Class.new\(\*args\)\s+at #{@tst_file}:28/,
|
176
|
+
/#2 <top \(required\)>\s+at #{@tst_file}:28/
|
115
177
|
end
|
116
178
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
enter 'set nofullpath', 'break 16', 'cont', 'where'
|
122
|
-
debug_file 'frame'
|
123
|
-
check_output_includes \
|
124
|
-
/--> #0 A.d(e#String) at #{short_path(fullpath('frame'))}:16/x,
|
125
|
-
/#1 A.c at #{short_path(fullpath('frame'))}:12/x,
|
126
|
-
/#2 A.b at #{short_path(fullpath('frame'))}:8/x
|
127
|
-
end
|
179
|
+
it 'must not navigate "up" to c-frames' do
|
180
|
+
enter 'up', 'eval local_var'
|
181
|
+
debug_file 'frame'
|
182
|
+
check_output_includes '"hola"'
|
128
183
|
end
|
129
|
-
end
|
130
184
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
it 'displays current backtrace with callstyle "long"' do
|
136
|
-
enter 'break 16', 'cont', 'where'
|
137
|
-
debug_file 'frame'
|
138
|
-
check_output_includes \
|
139
|
-
/--> #0 A.d(e#String) at #{fullpath('frame')}:16/x,
|
140
|
-
/#1 A.c at #{fullpath('frame')}:12/x ,
|
141
|
-
/#2 A.b at #{fullpath('frame')}:8/x ,
|
142
|
-
/#3 A.a at #{fullpath('frame')}:5/x
|
143
|
-
end
|
185
|
+
it 'must not navigate "down" to c-frames' do
|
186
|
+
enter 'up', 'down', 'eval f'
|
187
|
+
debug_file 'frame'
|
188
|
+
check_output_includes '"f"'
|
144
189
|
end
|
145
190
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
enter 'break 16', 'cont', 'where'
|
151
|
-
debug_file 'frame'
|
152
|
-
check_output_includes /--> #0 d(e) at #{fullpath('frame')}:16/x,
|
153
|
-
/#1 c at #{fullpath('frame')}:12/x,
|
154
|
-
/#2 b at #{fullpath('frame')}:8/x,
|
155
|
-
/#3 a at #{fullpath('frame')}:5/x
|
156
|
-
end
|
191
|
+
it 'must not jump straigh to c-frames' do
|
192
|
+
enter 'frame 1'
|
193
|
+
debug_file 'frame'
|
194
|
+
check_output_includes "Can't navigate to c-frame", interface.error_queue
|
157
195
|
end
|
158
196
|
end
|
159
197
|
|
@@ -163,5 +201,4 @@ class TestFrame < TestDsl::TestCase
|
|
163
201
|
debug_file('post_mortem') { $state.line.must_equal 8 }
|
164
202
|
end
|
165
203
|
end
|
166
|
-
|
167
204
|
end
|
data/test/info_test.rb
CHANGED
@@ -233,9 +233,9 @@ class TestInfo < TestDsl::TestCase
|
|
233
233
|
it 'must show stack info' do
|
234
234
|
enter 'set fullpath', 'break 20', 'cont', 'info stack'
|
235
235
|
debug_file 'info'
|
236
|
-
check_output_includes /--> #0
|
237
|
-
/#1
|
238
|
-
/#2 <
|
236
|
+
check_output_includes /--> #0 InfoExample.a\s+at #{fullpath('info')}:20/,
|
237
|
+
/#1 InfoExample.b\s+at #{fullpath('info')}:30/,
|
238
|
+
/#2 <top \(required\)>\s+at #{fullpath('info')}:36/
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
@@ -255,7 +255,7 @@ class TestInfo < TestDsl::TestCase
|
|
255
255
|
debug_file 'info'
|
256
256
|
check_output_includes 'a = "1111111111111111111111...',
|
257
257
|
'b = 2',
|
258
|
-
/self = #<
|
258
|
+
/self = #<InfoExample:\S+.../,
|
259
259
|
'@bla = "blabla"',
|
260
260
|
'@foo = "bar"'
|
261
261
|
end
|
@@ -264,7 +264,7 @@ class TestInfo < TestDsl::TestCase
|
|
264
264
|
enter 'break 26', 'cont', 'info variables'
|
265
265
|
debug_file 'info'
|
266
266
|
check_output_includes 'a = *Error in evaluation*',
|
267
|
-
/self = #<
|
267
|
+
/self = #<InfoExample:\S+.../,
|
268
268
|
'@bla = "blabla"',
|
269
269
|
'@foo = "bar"'
|
270
270
|
end
|
data/test/method_test.rb
CHANGED
@@ -5,14 +5,14 @@ class TestMethod < TestDsl::TestCase
|
|
5
5
|
|
6
6
|
describe 'show instance method of a class' do
|
7
7
|
it 'must show using full command name' do
|
8
|
-
enter 'break 15', 'cont', 'method
|
8
|
+
enter 'break 15', 'cont', 'method MethodExample'
|
9
9
|
debug_file 'method'
|
10
10
|
check_output_includes /bla/
|
11
11
|
check_output_doesnt_include /foo/
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'must show using shortcut' do
|
15
|
-
enter 'break 15', 'cont', 'm
|
15
|
+
enter 'break 15', 'cont', 'm MethodExample'
|
16
16
|
debug_file 'method'
|
17
17
|
check_output_includes /bla/
|
18
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: byebug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Rodríguez
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-08-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: columnize
|
@@ -314,3 +314,4 @@ test_files:
|
|
314
314
|
- test/test_helper.rb
|
315
315
|
- test/trace_test.rb
|
316
316
|
- test/variables_test.rb
|
317
|
+
has_rdoc:
|