byebug 1.6.1 → 1.7.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/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:
|