debug 1.0.0.beta2 → 1.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +23 -19
- data/lib/debug/breakpoint.rb +5 -2
- data/lib/debug/config.rb +18 -12
- data/lib/debug/session.rb +38 -13
- data/lib/debug/thread_client.rb +61 -20
- data/lib/debug/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9702de02ad9d9aab11e0f0113a3596110222f92178e2918e6f4c5ad66fb5e3fb
|
4
|
+
data.tar.gz: 6f8552da80d13f0c597223fa651a49f44810d7106feb73c8a93d73249c74a987
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a2386cd5fcde06d356cb35e1d5ff637c587c33a4fdf9e3866d11761276a31cf5586d383b8cd8f6074be24a681592db7d577b8fcf3270d63afff9256ddaaa78f
|
7
|
+
data.tar.gz: 373039bc43b6071d77c4bb103453258a50668224ea581b4fd0b5ec0bf3df7c4b95702e2bc3723e35c55e238aaf6fa9297090fa7daf8fe4c6eee22124f1087daf
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -321,10 +321,14 @@ The `<...>` notation means the argument.
|
|
321
321
|
* Finish this frame. Resume the program until the current frame is finished.
|
322
322
|
* `c[ontinue]`
|
323
323
|
* Resume the program.
|
324
|
-
* `q[uit]` or
|
324
|
+
* `q[uit]` or `Ctrl-D`
|
325
325
|
* Finish debugger (with the debuggee process on non-remote debugging).
|
326
|
-
* `
|
327
|
-
*
|
326
|
+
* `q[uit]!`
|
327
|
+
* Same as q[uit] but without the confirmation prompt.
|
328
|
+
* `kill`
|
329
|
+
* Stop the debuggee process with `Kernal#exit!`.
|
330
|
+
* `kill!`
|
331
|
+
* Same as kill but without the confirmation prompt.
|
328
332
|
|
329
333
|
### Breakpoint
|
330
334
|
|
@@ -346,7 +350,7 @@ The `<...>` notation means the argument.
|
|
346
350
|
* `catch <Error>`
|
347
351
|
* Set breakpoint on raising `<Error>`.
|
348
352
|
* `watch <expr>`
|
349
|
-
* Stop the execution when the result of
|
353
|
+
* Stop the execution when the result of `<expr>` is changed.
|
350
354
|
* Note that this feature is super slow.
|
351
355
|
* `del[ete]`
|
352
356
|
* delete all breakpoints.
|
@@ -388,13 +392,13 @@ The `<...>` notation means the argument.
|
|
388
392
|
### Frame control
|
389
393
|
|
390
394
|
* `f[rame]`
|
391
|
-
* Show current frame.
|
395
|
+
* Show the current frame.
|
392
396
|
* `f[rame] <framenum>`
|
393
|
-
* Specify frame. Evaluation are run on
|
397
|
+
* Specify a current frame. Evaluation are run on specified frame.
|
394
398
|
* `up`
|
395
|
-
* Specify upper frame.
|
399
|
+
* Specify the upper frame.
|
396
400
|
* `down`
|
397
|
-
* Specify
|
401
|
+
* Specify the lower frame.
|
398
402
|
|
399
403
|
### Evaluate
|
400
404
|
|
@@ -438,23 +442,23 @@ Debug console mode:
|
|
438
442
|
|
439
443
|
Debug console mode runs Ruby program with the debug console.
|
440
444
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
445
|
+
rdbg target.rb foo bar starts like 'ruby target.rb foo bar'.
|
446
|
+
rdbg -- -r foo -e bar starts like 'ruby -r foo -e bar'.
|
447
|
+
rdbg -O target.rb foo bar starts and accepts attaching with UNIX domain socket.
|
448
|
+
rdbg -O --port 1234 target.rb foo bar starts accepts attaching with TCP/IP localhost:1234.
|
449
|
+
rdbg -O --port 1234 -- -r foo -e bar starts accepts attaching with TCP/IP localhost:1234.
|
446
450
|
|
447
451
|
Attach mode:
|
448
452
|
-A, --attach Attach to debuggee process.
|
449
453
|
|
450
454
|
Attach mode attaches the remote debug console to the debuggee process.
|
451
455
|
|
452
|
-
'
|
453
|
-
|
454
|
-
|
455
|
-
'
|
456
|
-
'
|
457
|
-
'
|
456
|
+
'rdbg -A' tries to connect via UNIX domain socket.
|
457
|
+
If there are multiple processes are waiting for the
|
458
|
+
debugger connection, list possible debuggee names.
|
459
|
+
'rdbg -A path' tries to connect via UNIX domain socket with given path name.
|
460
|
+
'rdbg -A port' tries to connect to localhost:port via TCP/IP.
|
461
|
+
'rdbg -A host port' tries to connect to host:port via TCP/IP.
|
458
462
|
|
459
463
|
```
|
460
464
|
|
data/lib/debug/breakpoint.rb
CHANGED
@@ -28,7 +28,7 @@ module DEBUGGER__
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def disable
|
31
|
-
@tp
|
31
|
+
@tp&.disable
|
32
32
|
end
|
33
33
|
|
34
34
|
def enabled?
|
@@ -144,7 +144,10 @@ module DEBUGGER__
|
|
144
144
|
nearest = nil # NearestISeq
|
145
145
|
|
146
146
|
ObjectSpace.each_iseq{|iseq|
|
147
|
-
if (iseq.absolute_path || iseq.path) == self.path &&
|
147
|
+
if (iseq.absolute_path || iseq.path) == self.path &&
|
148
|
+
iseq.first_lineno <= self.line &&
|
149
|
+
iseq.type != :ensure # ensure iseq is copied (duplicated)
|
150
|
+
|
148
151
|
iseq.traceable_lines_norec(line_events = {})
|
149
152
|
lines = line_events.keys.sort
|
150
153
|
|
data/lib/debug/config.rb
CHANGED
@@ -30,12 +30,16 @@ module DEBUGGER__
|
|
30
30
|
end
|
31
31
|
|
32
32
|
CONFIG_MAP = {
|
33
|
-
#
|
33
|
+
# boot setting
|
34
34
|
nonstop: 'RUBY_DEBUG_NONSTOP', # Nonstop mode ('1' is nonstop)
|
35
35
|
init_script: 'RUBY_DEBUG_INIT_SCRIPT', # debug command script path loaded at first stop
|
36
36
|
commands: 'RUBY_DEBUG_COMMANDS', # debug commands invoked at first stop. commands should be separated by ';;'
|
37
|
+
|
38
|
+
# UI setting
|
37
39
|
show_src_lines: 'RUBY_DEBUG_SHOW_SRC_LINES', # Show n lines source code on breakpoint (default: 10 lines).
|
38
40
|
show_frames: 'RUBY_DEBUG_SHOW_FRAMES', # Show n frames on breakpoint (default: 2 frames).
|
41
|
+
use_short_path: 'RUBY_DEBUG_USE_SHORT_PATH', # Show shoten PATH (like $(Gem)/foo.rb).
|
42
|
+
skip_nosrc: 'RUBY_DEBUG_SKIP_NOSRC', # Skip on no source code lines (default: false).
|
39
43
|
|
40
44
|
# remote
|
41
45
|
port: 'RUBY_DEBUG_PORT', # TCP/IP remote debugging: port
|
@@ -86,14 +90,16 @@ module DEBUGGER__
|
|
86
90
|
config[:host] = host
|
87
91
|
end
|
88
92
|
|
93
|
+
rdbg = 'rdbg'
|
94
|
+
|
89
95
|
o.separator ''
|
90
96
|
o.separator ' Debug console mode runs Ruby program with the debug console.'
|
91
97
|
o.separator ''
|
92
|
-
o.separator " #{
|
93
|
-
o.separator " #{
|
94
|
-
o.separator " #{
|
95
|
-
o.separator " #{
|
96
|
-
o.separator " #{
|
98
|
+
o.separator " #{rdbg} target.rb foo bar starts like 'ruby target.rb foo bar'."
|
99
|
+
o.separator " #{rdbg} -- -r foo -e bar starts like 'ruby -r foo -e bar'."
|
100
|
+
o.separator " #{rdbg} -O target.rb foo bar starts and accepts attaching with UNIX domain socket."
|
101
|
+
o.separator " #{rdbg} -O --port 1234 target.rb foo bar starts accepts attaching with TCP/IP localhost:1234."
|
102
|
+
o.separator " #{rdbg} -O --port 1234 -- -r foo -e bar starts accepts attaching with TCP/IP localhost:1234."
|
97
103
|
|
98
104
|
o.separator ''
|
99
105
|
o.separator 'Attach mode:'
|
@@ -104,12 +110,12 @@ module DEBUGGER__
|
|
104
110
|
o.separator ''
|
105
111
|
o.separator ' Attach mode attaches the remote debug console to the debuggee process.'
|
106
112
|
o.separator ''
|
107
|
-
o.separator " '#{
|
108
|
-
o.separator " #{' ' *
|
109
|
-
o.separator " #{' ' *
|
110
|
-
o.separator " '#{
|
111
|
-
o.separator " '#{
|
112
|
-
o.separator " '#{
|
113
|
+
o.separator " '#{rdbg} -A' tries to connect via UNIX domain socket."
|
114
|
+
o.separator " #{' ' * rdbg.size} If there are multiple processes are waiting for the"
|
115
|
+
o.separator " #{' ' * rdbg.size} debugger connection, list possible debuggee names."
|
116
|
+
o.separator " '#{rdbg} -A path' tries to connect via UNIX domain socket with given path name."
|
117
|
+
o.separator " '#{rdbg} -A port' tries to connect to localhost:port via TCP/IP."
|
118
|
+
o.separator " '#{rdbg} -A host port' tries to connect to host:port via TCP/IP."
|
113
119
|
end
|
114
120
|
|
115
121
|
opt.parse!(argv)
|
data/lib/debug/session.rb
CHANGED
@@ -4,7 +4,11 @@
|
|
4
4
|
:has_return_value, :return_value, :show_line)
|
5
5
|
end
|
6
6
|
|
7
|
-
|
7
|
+
if File.exist? File.join(__dir__, 'debug.so')
|
8
|
+
require_relative 'debug.so'
|
9
|
+
else
|
10
|
+
require "debug/debug"
|
11
|
+
end
|
8
12
|
|
9
13
|
require_relative 'source_repository'
|
10
14
|
require_relative 'breakpoint'
|
@@ -133,6 +137,9 @@ module DEBUGGER__
|
|
133
137
|
wait_command_loop tc
|
134
138
|
end
|
135
139
|
end
|
140
|
+
ensure
|
141
|
+
@bps.each{|k, bp| bp.disable}
|
142
|
+
@th_clients.each{|th, thc| thc.close}
|
136
143
|
end
|
137
144
|
|
138
145
|
@management_threads = [@session_server]
|
@@ -224,9 +231,9 @@ module DEBUGGER__
|
|
224
231
|
when 'c', 'continue'
|
225
232
|
@tc << :continue
|
226
233
|
|
227
|
-
# * `q[uit]` or
|
234
|
+
# * `q[uit]` or `Ctrl-D`
|
228
235
|
# * Finish debugger (with the debuggee process on non-remote debugging).
|
229
|
-
when 'q', 'quit'
|
236
|
+
when 'q', 'quit'
|
230
237
|
if ask 'Really quit?'
|
231
238
|
@ui.quit arg.to_i
|
232
239
|
@tc << :continue
|
@@ -234,15 +241,26 @@ module DEBUGGER__
|
|
234
241
|
return :retry
|
235
242
|
end
|
236
243
|
|
237
|
-
# * `
|
238
|
-
# *
|
239
|
-
when '
|
244
|
+
# * `q[uit]!`
|
245
|
+
# * Same as q[uit] but without the confirmation prompt.
|
246
|
+
when 'q!', 'quit!'
|
247
|
+
@ui.quit arg.to_i
|
248
|
+
@tc << :continue
|
249
|
+
|
250
|
+
# * `kill`
|
251
|
+
# * Stop the debuggee process with `Kernal#exit!`.
|
252
|
+
when 'kill'
|
240
253
|
if ask 'Really kill?'
|
241
254
|
exit! (arg || 1).to_i
|
242
255
|
else
|
243
256
|
return :retry
|
244
257
|
end
|
245
258
|
|
259
|
+
# * `kill!`
|
260
|
+
# * Same as kill but without the confirmation prompt.
|
261
|
+
when 'kill!'
|
262
|
+
exit! (arg || 1).to_i
|
263
|
+
|
246
264
|
### Breakpoint
|
247
265
|
|
248
266
|
# * `b[reak]`
|
@@ -312,7 +330,7 @@ module DEBUGGER__
|
|
312
330
|
return :retry
|
313
331
|
|
314
332
|
# * `watch <expr>`
|
315
|
-
# * Stop the execution when the result of
|
333
|
+
# * Stop the execution when the result of `<expr>` is changed.
|
316
334
|
# * Note that this feature is super slow.
|
317
335
|
when 'wat', 'watch'
|
318
336
|
if arg
|
@@ -410,7 +428,7 @@ module DEBUGGER__
|
|
410
428
|
# * Show the result of `<expr>` at every suspended timing.
|
411
429
|
when 'display'
|
412
430
|
if arg && !arg.empty?
|
413
|
-
@displays << arg
|
431
|
+
@displays << arg
|
414
432
|
@tc << [:eval, :try_display, @displays]
|
415
433
|
else
|
416
434
|
@tc << [:eval, :display, @displays]
|
@@ -459,19 +477,19 @@ module DEBUGGER__
|
|
459
477
|
### Frame control
|
460
478
|
|
461
479
|
# * `f[rame]`
|
462
|
-
# * Show current frame.
|
480
|
+
# * Show the current frame.
|
463
481
|
# * `f[rame] <framenum>`
|
464
|
-
# * Specify frame. Evaluation are run on
|
482
|
+
# * Specify a current frame. Evaluation are run on specified frame.
|
465
483
|
when 'frame', 'f'
|
466
484
|
@tc << [:frame, :set, arg]
|
467
485
|
|
468
486
|
# * `up`
|
469
|
-
# * Specify upper frame.
|
487
|
+
# * Specify the upper frame.
|
470
488
|
when 'up'
|
471
489
|
@tc << [:frame, :up]
|
472
490
|
|
473
491
|
# * `down`
|
474
|
-
# * Specify
|
492
|
+
# * Specify the lower frame.
|
475
493
|
when 'down'
|
476
494
|
@tc << [:frame, :down]
|
477
495
|
|
@@ -801,7 +819,7 @@ module DEBUGGER__
|
|
801
819
|
end
|
802
820
|
end
|
803
821
|
|
804
|
-
## event
|
822
|
+
## event
|
805
823
|
|
806
824
|
def on_load iseq, src
|
807
825
|
@sr.add iseq, src
|
@@ -849,6 +867,13 @@ module DEBUGGER__
|
|
849
867
|
File.realpath(File.expand_path(file))
|
850
868
|
rescue Errno::ENOENT
|
851
869
|
return file if file == '-e'
|
870
|
+
$LOAD_PATH.each do |lp|
|
871
|
+
libpath = File.join(lp, file)
|
872
|
+
return File.realpath(libpath)
|
873
|
+
rescue Errno::ENOENT
|
874
|
+
# next
|
875
|
+
end
|
876
|
+
|
852
877
|
raise
|
853
878
|
end
|
854
879
|
|
data/lib/debug/thread_client.rb
CHANGED
@@ -24,6 +24,10 @@ module DEBUGGER__
|
|
24
24
|
set_mode nil
|
25
25
|
end
|
26
26
|
|
27
|
+
def close
|
28
|
+
@q_cmd.close
|
29
|
+
end
|
30
|
+
|
27
31
|
def inspect
|
28
32
|
"#<DBG:TC #{self.id}:#{self.mode}@#{@thread.backtrace[-1]}>"
|
29
33
|
end
|
@@ -125,6 +129,8 @@ module DEBUGGER__
|
|
125
129
|
next if SESSION.break? tp.path, tp.lineno
|
126
130
|
next if !yield
|
127
131
|
next if tp.path.start_with?(__dir__)
|
132
|
+
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
133
|
+
|
128
134
|
tp.disable
|
129
135
|
on_suspend tp.event, tp
|
130
136
|
}
|
@@ -134,6 +140,8 @@ module DEBUGGER__
|
|
134
140
|
next if thread != Thread.current
|
135
141
|
next if SESSION.break? tp.path, tp.lineno
|
136
142
|
next if !yield
|
143
|
+
next unless File.exist?(tp.path) if CONFIG[:skip_nosrc]
|
144
|
+
|
137
145
|
tp.disable
|
138
146
|
on_suspend tp.event, tp
|
139
147
|
}
|
@@ -197,10 +205,12 @@ module DEBUGGER__
|
|
197
205
|
frame.show_line = end_line
|
198
206
|
end
|
199
207
|
|
200
|
-
if start_line != end_line
|
201
|
-
puts "[#{start_line+1}, #{end_line}] in #{path}"
|
208
|
+
if start_line != end_line && max_lines
|
209
|
+
puts "[#{start_line+1}, #{end_line}] in #{pretty_path(path)}" if !update_line && max_lines != 1
|
202
210
|
puts lines[start_line ... end_line]
|
203
211
|
end
|
212
|
+
else # no file lines
|
213
|
+
puts "# No sourcefile available for #{path}"
|
204
214
|
end
|
205
215
|
end
|
206
216
|
end
|
@@ -287,9 +297,15 @@ module DEBUGGER__
|
|
287
297
|
}.compact.join(', ')
|
288
298
|
end
|
289
299
|
|
300
|
+
def get_singleton_class obj
|
301
|
+
obj.singleton_class # TODO: don't use it
|
302
|
+
rescue TypeError
|
303
|
+
nil
|
304
|
+
end
|
305
|
+
|
290
306
|
def klass_sig frame
|
291
307
|
klass = frame.class
|
292
|
-
if klass == frame.self
|
308
|
+
if klass == get_singleton_class(frame.self)
|
293
309
|
"#{frame.self}."
|
294
310
|
else
|
295
311
|
"#{frame.class}#"
|
@@ -307,40 +323,65 @@ module DEBUGGER__
|
|
307
323
|
end
|
308
324
|
end
|
309
325
|
|
326
|
+
HOME = ENV['HOME'] ? (ENV['HOME'] + '/') : nil
|
327
|
+
|
328
|
+
def pretty_path path
|
329
|
+
use_short_path = CONFIG[:use_short_path]
|
330
|
+
|
331
|
+
case
|
332
|
+
when use_short_path && path.start_with?(dir = RbConfig::CONFIG["rubylibdir"] + '/')
|
333
|
+
path.sub(dir, '$(rubylibdir)/')
|
334
|
+
when use_short_path && Gem.path.any? do |gp|
|
335
|
+
path.start_with?(dir = gp + '/gems/')
|
336
|
+
end
|
337
|
+
path.sub(dir, '$(Gem)/')
|
338
|
+
when HOME && path.start_with?(HOME)
|
339
|
+
path.sub(HOME, '~/')
|
340
|
+
else
|
341
|
+
path
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def pretty_location loc
|
346
|
+
" at #{pretty_path(loc.path)}:#{loc.lineno}"
|
347
|
+
end
|
348
|
+
|
310
349
|
def frame_str i
|
311
|
-
buff = ''.dup
|
312
350
|
frame = @target_frames[i]
|
313
351
|
b = frame.binding
|
314
352
|
|
315
|
-
|
316
|
-
if b
|
317
|
-
buff << "##{i}\t#{frame.location}"
|
318
|
-
else
|
319
|
-
buff << "##{i}\t[C] #{frame.location}"
|
320
|
-
end
|
353
|
+
cur_str = (@current_frame_index == i ? '=>' : ' ')
|
321
354
|
|
322
355
|
if b && (iseq = frame.iseq)
|
323
356
|
if iseq.type == :block
|
324
357
|
if (argc = iseq.argc) > 0
|
325
358
|
args = parameters_info b, iseq.locals[0...argc]
|
326
|
-
|
359
|
+
args_str = "{|#{args}|}"
|
327
360
|
end
|
361
|
+
|
362
|
+
label_prefix = frame.location.label.sub('block'){ "block#{args_str}" }
|
363
|
+
ci_str = label_prefix
|
364
|
+
elsif (callee = b.eval('__callee__', __FILE__, __LINE__)) && (argc = iseq.argc) > 0
|
365
|
+
args = parameters_info b, iseq.locals[0...argc]
|
366
|
+
ksig = klass_sig frame
|
367
|
+
ci_str = "#{ksig}#{callee}(#{args})"
|
328
368
|
else
|
329
|
-
|
330
|
-
args = parameters_info b, iseq.locals[0...argc]
|
331
|
-
ksig = klass_sig frame
|
332
|
-
buff << " #{ksig}#{callee}(#{args})"
|
333
|
-
end
|
369
|
+
ci_str = frame.location.label
|
334
370
|
end
|
335
371
|
|
372
|
+
loc_str = "#{pretty_location(frame.location)}"
|
373
|
+
|
336
374
|
if frame.has_return_value
|
337
|
-
|
375
|
+
return_str = " #=> #{short_inspect(frame.return_value)}"
|
338
376
|
end
|
339
377
|
else
|
340
|
-
|
378
|
+
ksig = klass_sig frame
|
379
|
+
callee = frame.location.base_label
|
380
|
+
ci_str = "[C] #{ksig}#{callee}"
|
381
|
+
loc_str = "#{pretty_location(frame.location)}"
|
341
382
|
end
|
342
383
|
|
343
|
-
|
384
|
+
"#{cur_str}##{i}\t#{ci_str}#{loc_str}#{return_str}"
|
344
385
|
end
|
345
386
|
|
346
387
|
def show_frames max = (@target_frames || []).size
|
@@ -351,7 +392,7 @@ module DEBUGGER__
|
|
351
392
|
break if i >= size
|
352
393
|
puts frame_str(i)
|
353
394
|
}
|
354
|
-
puts "
|
395
|
+
puts " # and #{size - max} frames (use `bt' command for all frames)" if max < size
|
355
396
|
end
|
356
397
|
end
|
357
398
|
|
data/lib/debug/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Sasada
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-05-
|
11
|
+
date: 2021-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Debugging functionality for Ruby. This is completely rewritten debug.rb
|
14
14
|
which was contained by the encient Ruby versions.
|