byebug 1.3.0 → 1.3.1
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 -0
- data/GUIDE.md +209 -0
- data/README.md +11 -2
- data/Rakefile +12 -0
- data/ext/byebug/byebug.c +50 -53
- data/ext/byebug/context.c +0 -24
- data/lib/byebug.rb +23 -7
- data/lib/byebug/command.rb +35 -24
- data/lib/byebug/commands/breakpoints.rb +24 -35
- data/lib/byebug/commands/catchpoint.rb +13 -17
- data/lib/byebug/commands/condition.rb +14 -19
- data/lib/byebug/commands/continue.rb +5 -7
- data/lib/byebug/commands/display.rb +3 -3
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/enable.rb +18 -45
- data/lib/byebug/commands/eval.rb +1 -1
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/frame.rb +24 -22
- data/lib/byebug/commands/info.rb +91 -122
- data/lib/byebug/commands/jump.rb +3 -8
- data/lib/byebug/commands/list.rb +2 -2
- data/lib/byebug/commands/method.rb +6 -8
- data/lib/byebug/commands/save.rb +1 -1
- data/lib/byebug/commands/set.rb +0 -12
- data/lib/byebug/commands/show.rb +9 -21
- data/lib/byebug/commands/variables.rb +3 -3
- data/lib/byebug/context.rb +13 -2
- data/lib/byebug/interface.rb +13 -7
- data/lib/byebug/processor.rb +23 -25
- data/lib/byebug/version.rb +1 -1
- data/old_doc/primes.rb +1 -4
- data/test/continue_test.rb +2 -9
- data/test/examples/list.rb +1 -1
- data/test/examples/trace.rb +1 -0
- data/test/help_test.rb +1 -1
- data/test/info_test.rb +3 -3
- data/test/list_test.rb +7 -1
- data/test/method_test.rb +0 -1
- data/test/show_test.rb +8 -0
- data/test/support/matchers.rb +4 -2
- data/test/trace_test.rb +18 -1
- metadata +2 -2
data/lib/byebug/commands/eval.rb
CHANGED
@@ -16,10 +16,11 @@ module Byebug
|
|
16
16
|
end
|
17
17
|
|
18
18
|
if abs_frame_pos >= context.stack_size then
|
19
|
-
|
20
|
-
|
19
|
+
return \
|
20
|
+
errmsg "Adjusting would put us beyond the oldest (initial) frame.\n"
|
21
21
|
elsif abs_frame_pos < 0 then
|
22
|
-
|
22
|
+
return \
|
23
|
+
errmsg "Adjusting would put us beyond the newest (innermost) frame.\n"
|
23
24
|
return
|
24
25
|
end
|
25
26
|
|
@@ -28,25 +29,26 @@ module Byebug
|
|
28
29
|
@state.frame_pos = abs_frame_pos
|
29
30
|
end
|
30
31
|
|
31
|
-
@state.file = context.frame_file
|
32
|
-
@state.line = context.frame_line
|
32
|
+
@state.file = @state.context.frame_file @state.frame_pos
|
33
|
+
@state.line = @state.context.frame_line @state.frame_pos
|
33
34
|
|
34
|
-
print_frame
|
35
|
+
print_frame @state.frame_pos, false
|
35
36
|
end
|
36
37
|
|
37
|
-
def get_frame_call(prefix, pos
|
38
|
-
id = context.frame_method(pos)
|
38
|
+
def get_frame_call(prefix, pos)
|
39
|
+
id = @state.context.frame_method(pos)
|
39
40
|
return "<main>" unless id
|
40
41
|
|
41
|
-
klass = context.frame_class(pos)
|
42
|
+
klass = @state.context.frame_class(pos)
|
43
|
+
|
42
44
|
if Command.settings[:callstyle] != :short && klass
|
43
45
|
call_str = "#{klass}.#{id.id2name}"
|
44
46
|
else
|
45
47
|
call_str = "#{id.id2name}"
|
46
48
|
end
|
47
49
|
|
48
|
-
args = context.frame_args
|
49
|
-
locals = context.frame_locals
|
50
|
+
args = @state.context.frame_args pos
|
51
|
+
locals = @state.context.frame_locals pos
|
50
52
|
if args.any?
|
51
53
|
call_str += "("
|
52
54
|
args.each_with_index do |name, i|
|
@@ -60,7 +62,7 @@ module Byebug
|
|
60
62
|
end
|
61
63
|
call_str += "#{name}##{klass}, "
|
62
64
|
when :tracked
|
63
|
-
arg_info = context.frame_args_info
|
65
|
+
arg_info = context.frame_args_info pos
|
64
66
|
if arg_info && arg_info.size > i
|
65
67
|
call_str += "#{name}: #{arg_info[i].inspect}, "
|
66
68
|
else
|
@@ -84,10 +86,9 @@ module Byebug
|
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
87
|
-
def print_frame(pos, mark_current = true
|
88
|
-
file = context.frame_file
|
89
|
-
line = context.frame_line
|
90
|
-
klass = context.frame_class(pos)
|
89
|
+
def print_frame(pos, mark_current = true)
|
90
|
+
file = @state.context.frame_file pos
|
91
|
+
line = @state.context.frame_line pos
|
91
92
|
|
92
93
|
unless Command.settings[:frame_fullpath]
|
93
94
|
path_components = file.split(/[\\\/]/)
|
@@ -104,7 +105,7 @@ module Byebug
|
|
104
105
|
end
|
105
106
|
|
106
107
|
frame_str += sprintf "#%-2d ", pos
|
107
|
-
frame_str += get_frame_call
|
108
|
+
frame_str += get_frame_call frame_str, pos
|
108
109
|
file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}"
|
109
110
|
if frame_str.size + file_line.size + 1 > Command.settings[:width]
|
110
111
|
frame_str += "\n #{file_line}\n"
|
@@ -129,9 +130,10 @@ module Byebug
|
|
129
130
|
# ignoring additional caller entries. sentinal is set by byebug, but if it's
|
130
131
|
# nil then additional entries are presumably ones that we haven't recorded
|
131
132
|
# in context
|
132
|
-
def truncated_callstack?(
|
133
|
-
recorded_size = context.stack_size
|
134
|
-
to_find_fl =
|
133
|
+
def truncated_callstack?(sentinal=nil, cs=caller)
|
134
|
+
recorded_size = @state.context.stack_size
|
135
|
+
to_find_fl =
|
136
|
+
"#{@state.context.frame_file(0)}:#{@state.context.frame_line(0)}"
|
135
137
|
top_discard = false
|
136
138
|
cs.each_with_index do |fl, i|
|
137
139
|
fl.gsub!(/in `.*'$/, '')
|
@@ -166,7 +168,7 @@ module Byebug
|
|
166
168
|
|
167
169
|
def execute
|
168
170
|
print_backtrace
|
169
|
-
if truncated_callstack?(
|
171
|
+
if truncated_callstack?(Byebug.start_sentinal)
|
170
172
|
print \
|
171
173
|
"Warning: saved frames may be incomplete; compare with caller(0)\n"
|
172
174
|
end
|
@@ -261,7 +263,7 @@ module Byebug
|
|
261
263
|
%w(frame)
|
262
264
|
end
|
263
265
|
|
264
|
-
def
|
266
|
+
def description
|
265
267
|
%{
|
266
268
|
f[rame][ frame-number]
|
267
269
|
|
data/lib/byebug/commands/info.rb
CHANGED
@@ -2,10 +2,8 @@ module Byebug
|
|
2
2
|
|
3
3
|
module InfoFunctions
|
4
4
|
def info_catch(*args)
|
5
|
-
unless @state.context
|
6
|
-
|
7
|
-
return
|
8
|
-
end
|
5
|
+
return print "No frame selected.\n" unless @state.context
|
6
|
+
|
9
7
|
if Byebug.catchpoints and not Byebug.catchpoints.empty?
|
10
8
|
Byebug.catchpoints.each do |exception, hits|
|
11
9
|
print "#{exception}: #{exception.is_a?(Class)}\n"
|
@@ -69,7 +67,7 @@ module Byebug
|
|
69
67
|
end
|
70
68
|
|
71
69
|
def execute
|
72
|
-
return help(
|
70
|
+
return print InfoCommand.help(nil) unless @match[1]
|
73
71
|
|
74
72
|
args = @match[1].split(/[ \t]+/)
|
75
73
|
param = args.shift
|
@@ -82,12 +80,11 @@ module Byebug
|
|
82
80
|
end
|
83
81
|
|
84
82
|
def info_args(*args)
|
85
|
-
unless @state.context
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
args = @state.context.frame_args(@state.frame_pos)
|
83
|
+
return errmsg "No frame selected.\n" unless @state.context
|
84
|
+
|
85
|
+
locals = @state.context.frame_locals
|
86
|
+
args = @state.context.frame_args
|
87
|
+
|
91
88
|
args.each do |name|
|
92
89
|
s = "#{name} = #{locals[name].inspect}"
|
93
90
|
pad_with_dots(s)
|
@@ -95,8 +92,20 @@ module Byebug
|
|
95
92
|
end
|
96
93
|
end
|
97
94
|
|
95
|
+
def info_breakpoint(brkpt)
|
96
|
+
expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}"
|
97
|
+
print "%-3d %-3s at %s:%s%s\n" %
|
98
|
+
[brkpt.id, brkpt.enabled? ? 'y' : 'n', brkpt.source, brkpt.pos, expr]
|
99
|
+
hits = brkpt.hit_count
|
100
|
+
if hits > 0
|
101
|
+
s = (hits > 1) ? 's' : ''
|
102
|
+
print "\tbreakpoint already hit #{hits} time#{s}\n"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
private :info_breakpoint
|
106
|
+
|
98
107
|
def info_breakpoints(*args)
|
99
|
-
return
|
108
|
+
return errmsg "\"info breakpoints\" not available here.\n" unless
|
100
109
|
@state.context
|
101
110
|
|
102
111
|
return print "No breakpoints.\n" if Byebug.breakpoints.empty?
|
@@ -109,50 +118,34 @@ module Byebug
|
|
109
118
|
brkpts.empty?
|
110
119
|
end
|
111
120
|
print "Num Enb What\n"
|
112
|
-
brkpts.each
|
113
|
-
print "%-3d %-3s at %s:%s%s\n", b.id,
|
114
|
-
b.enabled? ? 'y' : 'n',
|
115
|
-
b.source,
|
116
|
-
b.pos,
|
117
|
-
b.expr.nil? ? '' : " if #{b.expr}"
|
118
|
-
hits = b.hit_count
|
119
|
-
if hits > 0
|
120
|
-
s = (hits > 1) ? 's' : ''
|
121
|
-
print "\tbreakpoint already hit #{hits} time#{s}\n"
|
122
|
-
end
|
123
|
-
end
|
121
|
+
brkpts.each { |b| info_breakpoint(b) }
|
124
122
|
end
|
125
123
|
|
126
124
|
def info_display(*args)
|
127
|
-
unless
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
140
|
-
else
|
141
|
-
print "There are no auto-display expressions now.\n"
|
125
|
+
return errmsg "\"info display\" not available here.\n" unless
|
126
|
+
@state.context
|
127
|
+
|
128
|
+
return print "There are no auto-display expressions now.\n" unless
|
129
|
+
@state.display.find{|d| d[0]}
|
130
|
+
|
131
|
+
print "Auto-display expressions now in effect:\n" \
|
132
|
+
"Num Enb Expression\n"
|
133
|
+
n = 1
|
134
|
+
for d in @state.display
|
135
|
+
print "%3d: %s %s\n" % [n, (d[0] ? 'y' : 'n'), d[1]]
|
136
|
+
n += 1
|
142
137
|
end
|
143
138
|
end
|
144
139
|
|
145
140
|
def info_file_path(file)
|
146
141
|
path = LineCache.path(file)
|
147
|
-
if path != file
|
148
|
-
print " - #{path}"
|
149
|
-
end
|
142
|
+
print " - #{path}" if path and path != file
|
150
143
|
end
|
151
144
|
private :info_file_path
|
152
145
|
|
153
146
|
def info_file_lines(file)
|
154
147
|
lines = LineCache.size(file)
|
155
|
-
print "\t
|
148
|
+
print "\t #{lines} lines\n" if lines
|
156
149
|
end
|
157
150
|
private :info_file_lines
|
158
151
|
|
@@ -167,80 +160,69 @@ module Byebug
|
|
167
160
|
|
168
161
|
def info_file_mtime(file)
|
169
162
|
stat = LineCache.stat(file)
|
170
|
-
print "\t
|
163
|
+
print "\t#{stat.mtime}\n" if stat
|
171
164
|
end
|
172
165
|
private :info_file_mtime
|
173
166
|
|
174
167
|
def info_file_sha1(file)
|
175
|
-
print "\t
|
168
|
+
print "\t#{LineCache.sha1(file)}\n"
|
176
169
|
end
|
177
170
|
private :info_file_sha1
|
178
171
|
|
179
172
|
def info_file(*args)
|
180
173
|
return info_files unless args[0]
|
181
|
-
file = args[0]
|
182
174
|
|
183
|
-
param = args[1]
|
175
|
+
param = args[1] || 'basic'
|
184
176
|
|
185
177
|
subcmd = find(InfoFileSubcommands, param)
|
186
178
|
return errmsg "Invalid parameter #{param}\n" unless subcmd
|
187
179
|
|
188
|
-
unless LineCache::cached?(
|
189
|
-
unless LineCache::cached_script?(
|
190
|
-
return print "File #{
|
180
|
+
unless LineCache::cached?(args[0])
|
181
|
+
unless LineCache::cached_script?(args[0])
|
182
|
+
return print "File #{args[0]} is not cached\n"
|
191
183
|
end
|
192
|
-
LineCache::cache(
|
184
|
+
LineCache::cache(args[0], Command.settings[:autoreload])
|
193
185
|
end
|
194
186
|
|
195
|
-
print "File #{
|
196
|
-
info_file_path(
|
187
|
+
print "File #{args[0]}"
|
188
|
+
info_file_path(args[0]) if %w(all basic path).member?(subcmd.name)
|
197
189
|
print "\n"
|
198
190
|
|
199
|
-
info_file_lines(
|
200
|
-
info_file_breakpoints(
|
201
|
-
info_file_mtime(
|
202
|
-
info_file_sha1(
|
191
|
+
info_file_lines(args[0]) if %w(all basic lines).member?(subcmd.name)
|
192
|
+
info_file_breakpoints(args[0]) if %w(all breakpoints).member?(subcmd.name)
|
193
|
+
info_file_mtime(args[0]) if %w(all mtime).member?(subcmd.name)
|
194
|
+
info_file_sha1(args[0]) if %w(all sha1).member?(subcmd.name)
|
203
195
|
end
|
204
196
|
|
205
197
|
def info_files(*args)
|
206
198
|
files = LineCache::cached_files
|
207
199
|
files += SCRIPT_LINES__.keys unless 'stat' == args[0]
|
208
200
|
files.uniq.sort.each do |file|
|
209
|
-
|
210
|
-
|
211
|
-
print "
|
212
|
-
|
213
|
-
print " - %s\n", path
|
214
|
-
else
|
215
|
-
print "\n"
|
216
|
-
end
|
217
|
-
print "\t%s\n", stat.mtime if stat
|
201
|
+
print "File #{file}"
|
202
|
+
info_file_path(file)
|
203
|
+
print "\n"
|
204
|
+
info_file_mtime(file)
|
218
205
|
end
|
219
206
|
end
|
220
207
|
|
221
208
|
def info_instance_variables(*args)
|
222
|
-
unless
|
223
|
-
|
224
|
-
|
225
|
-
end
|
209
|
+
return errmsg "\"info instance_variables\" not available here.\n" unless
|
210
|
+
@state.context
|
211
|
+
|
226
212
|
obj = debug_eval('self')
|
227
213
|
var_list(obj.instance_variables)
|
228
214
|
end
|
229
215
|
|
230
216
|
def info_line(*args)
|
231
|
-
unless @state.context
|
232
|
-
|
233
|
-
return
|
234
|
-
end
|
235
|
-
print "Line %d of \"%s\"\n", @state.line, @state.file
|
217
|
+
return errmsg "\"info line\" not available here.\n" unless @state.context
|
218
|
+
print "Line #{@state.line} of \"#{@state.file}\"\n"
|
236
219
|
end
|
237
220
|
|
238
221
|
def info_locals(*args)
|
239
|
-
unless
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
locals = @state.context.frame_locals(@state.frame_pos)
|
222
|
+
return errmsg "\"info locals\" not available here.\n" unless
|
223
|
+
@state.context
|
224
|
+
|
225
|
+
locals = @state.context.frame_locals
|
244
226
|
locals.keys.sort.each do |name|
|
245
227
|
### FIXME: make a common routine
|
246
228
|
begin
|
@@ -272,8 +254,8 @@ module Byebug
|
|
272
254
|
private :info_stop_reason
|
273
255
|
|
274
256
|
def info_program(*args)
|
275
|
-
return
|
276
|
-
|
257
|
+
return errmsg "The program being debugged is not being run.\n" unless
|
258
|
+
@state.context
|
277
259
|
|
278
260
|
return print "The program crashed.\n" + Byebug.last_exception ?
|
279
261
|
"Exception: #{Byebug.last_exception.inspect}" : "" + "\n" if
|
@@ -284,31 +266,26 @@ module Byebug
|
|
284
266
|
end
|
285
267
|
|
286
268
|
def info_stack(*args)
|
287
|
-
|
288
|
-
|
289
|
-
return
|
290
|
-
end
|
269
|
+
return errmsg "\"info stack\" not available here.\n" unless @state.context
|
270
|
+
|
291
271
|
print_backtrace
|
292
272
|
end
|
293
273
|
|
294
274
|
def info_global_variables(*args)
|
295
|
-
unless
|
296
|
-
|
297
|
-
|
298
|
-
end
|
275
|
+
return errmsg "\"info global_variables\" not available here.\n" unless
|
276
|
+
@state.context
|
277
|
+
|
299
278
|
var_global
|
300
279
|
end
|
301
280
|
|
302
281
|
def info_variables(*args)
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
end
|
282
|
+
return errmsg "\"info variables\" not available here.\n" unless
|
283
|
+
@state.context
|
284
|
+
|
307
285
|
obj = debug_eval('self')
|
308
|
-
locals = @state.context.frame_locals
|
286
|
+
locals = @state.context.frame_locals
|
309
287
|
locals[:self] = @state.context.frame_self(@state.frame_pos)
|
310
288
|
locals.keys.sort.each do |name|
|
311
|
-
next if name =~ /^__dbg_/ # skip byebug pollution
|
312
289
|
### FIXME: make a common routine
|
313
290
|
begin
|
314
291
|
s = "#{name} = #{locals[name].inspect}"
|
@@ -320,37 +297,12 @@ module Byebug
|
|
320
297
|
end
|
321
298
|
end
|
322
299
|
pad_with_dots(s)
|
323
|
-
s.gsub!('%', '%%') # protect against printf format strings
|
324
300
|
print "#{s}\n"
|
325
301
|
end
|
326
302
|
var_list(obj.instance_variables, obj.instance_eval{binding()})
|
327
303
|
var_class_self
|
328
304
|
end
|
329
305
|
|
330
|
-
def help(args)
|
331
|
-
if args[1]
|
332
|
-
subcmd = find(Subcommands, args[1])
|
333
|
-
if subcmd
|
334
|
-
str = subcmd.short_help + '.'
|
335
|
-
if 'file' == subcmd.name and args[2]
|
336
|
-
subsubcmd = find(InfoFileSubcommands, args[2])
|
337
|
-
if subsubcmd
|
338
|
-
str += "\nInvalid \"file\" attribute \"#{args[2]}\"."
|
339
|
-
else
|
340
|
-
str += "\n" + subsubcmd.short_help + '.'
|
341
|
-
end
|
342
|
-
else
|
343
|
-
str += "\n" + subcmd.long_help if subcmd.long_help
|
344
|
-
end
|
345
|
-
else
|
346
|
-
str = "Invalid \"info\" subcommand \"#{args[1]}\"."
|
347
|
-
end
|
348
|
-
else
|
349
|
-
str = InfoCommand.description + format_subcmds(Subcommands)
|
350
|
-
end
|
351
|
-
print str
|
352
|
-
end
|
353
|
-
|
354
306
|
class << self
|
355
307
|
def names
|
356
308
|
%w(info)
|
@@ -360,10 +312,27 @@ module Byebug
|
|
360
312
|
%{
|
361
313
|
info[ subcommand]
|
362
314
|
|
363
|
-
Generic command for showing things about the program being
|
315
|
+
Generic command for showing things about the program being debugged.
|
364
316
|
}
|
365
317
|
end
|
318
|
+
|
319
|
+
def help(args)
|
320
|
+
return description + format_subcmds unless args and args[1]
|
321
|
+
|
322
|
+
return format_subcmd(args[1]) unless 'file' == args[1] and args[2]
|
323
|
+
|
324
|
+
str = subcmd.short_help + '.'
|
325
|
+
subsubcmd = find(InfoFileSubcommands, args[2])
|
326
|
+
if subsubcmd
|
327
|
+
str += "\nInvalid \"file\" attribute \"#{args[2]}\"."
|
328
|
+
else
|
329
|
+
str += "\n" + subsubcmd.short_help + '.'
|
330
|
+
end
|
331
|
+
|
332
|
+
return str
|
333
|
+
end
|
366
334
|
end
|
335
|
+
|
367
336
|
end
|
368
337
|
|
369
338
|
end
|