debug 1.0.0.beta2 → 1.0.0.beta3
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/.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.
|