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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0ed57ff87f1864d86d79c435081b12df6cb35bd4f24a3cb79f4a909887e5f41
4
- data.tar.gz: c342d515e9358e0cfdee353b5d5be1fbbb7bcf46cfdf3f925ace7a3acc2b6e90
3
+ metadata.gz: 9702de02ad9d9aab11e0f0113a3596110222f92178e2918e6f4c5ad66fb5e3fb
4
+ data.tar.gz: 6f8552da80d13f0c597223fa651a49f44810d7106feb73c8a93d73249c74a987
5
5
  SHA512:
6
- metadata.gz: 112d49a60540e034752e1c3d3721c213549cae4653c63041c3f3da08cf7bf01624e8a45c0ee88ff31270eef337cf8db3ca8de7d403eea550aff82621050e9e14
7
- data.tar.gz: e6800fb760a734419ed43fa04720b0bc75a815f0de4511df7f76a44b9b864c002eb6c9503f74e1a9471d335f671f0db12636e852cc6bac0366ba00d051e29b0b
6
+ metadata.gz: 1a2386cd5fcde06d356cb35e1d5ff637c587c33a4fdf9e3866d11761276a31cf5586d383b8cd8f6074be24a681592db7d577b8fcf3270d63afff9256ddaaa78f
7
+ data.tar.gz: 373039bc43b6071d77c4bb103453258a50668224ea581b4fd0b5ec0bf3df7c4b95702e2bc3723e35c55e238aaf6fa9297090fa7daf8fe4c6eee22124f1087daf
data/.gitignore CHANGED
@@ -6,4 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ *.bundle
9
10
  /Gemfile.lock
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 exit or `Ctrl-D`
324
+ * `q[uit]` or `Ctrl-D`
325
325
  * Finish debugger (with the debuggee process on non-remote debugging).
326
- * `kill` or `q[uit]!`
327
- * Stop the debuggee process.
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 <expr> is changed.
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 this frame environment.
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 down frame.
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
- exe/rdbg target.rb foo bar starts like 'ruby target.rb foo bar'.
442
- exe/rdbg -- -r foo -e bar starts like 'ruby -r foo -e bar'.
443
- exe/rdbg -O target.rb foo bar starts and accepts attaching with UNIX domain socket.
444
- exe/rdbg -O --port 1234 target.rb foo bar starts accepts attaching with TCP/IP localhost:1234.
445
- exe/rdbg -O --port 1234 -- -r foo -e bar starts accepts attaching with TCP/IP localhost:1234.
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
- 'exe/rdbg -A' tries to connect via UNIX domain socket.
453
- If there are multiple processes are waiting for the
454
- debugger connection, list possible debuggee names.
455
- 'exe/rdbg -A path' tries to connect via UNIX domain socket with given path name.
456
- 'exe/rdbg -A port' tries to connect localhost:port via TCP/IP.
457
- 'exe/rdbg -A host port' tries to connect host:port via TCP/IP.
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
 
@@ -28,7 +28,7 @@ module DEBUGGER__
28
28
  end
29
29
 
30
30
  def disable
31
- @tp.disable
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 && iseq.first_lineno <= self.line
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
- # execution preferences
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 " #{$0} target.rb foo bar starts like 'ruby target.rb foo bar'."
93
- o.separator " #{$0} -- -r foo -e bar starts like 'ruby -r foo -e bar'."
94
- o.separator " #{$0} -O target.rb foo bar starts and accepts attaching with UNIX domain socket."
95
- o.separator " #{$0} -O --port 1234 target.rb foo bar starts accepts attaching with TCP/IP localhost:1234."
96
- o.separator " #{$0} -O --port 1234 -- -r foo -e bar starts accepts attaching with TCP/IP localhost:1234."
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 " '#{$0} -A' tries to connect via UNIX domain socket."
108
- o.separator " #{' ' * $0.size} If there are multiple processes are waiting for the"
109
- o.separator " #{' ' * $0.size} debugger connection, list possible debuggee names."
110
- o.separator " '#{$0} -A path' tries to connect via UNIX domain socket with given path name."
111
- o.separator " '#{$0} -A port' tries to connect localhost:port via TCP/IP."
112
- o.separator " '#{$0} -A host port' tries to connect host:port via TCP/IP."
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
- require "debug/debug"
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 exit or `Ctrl-D`
234
+ # * `q[uit]` or `Ctrl-D`
228
235
  # * Finish debugger (with the debuggee process on non-remote debugging).
229
- when 'q', 'quit', 'exit'
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
- # * `kill` or `q[uit]!`
238
- # * Stop the debuggee process.
239
- when 'kill', 'quit!', 'q!'
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 <expr> is changed.
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 this frame environment.
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 down frame.
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
 
@@ -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}" unless update_line
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.singleton_class
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
- buff << (@current_frame_index == i ? '--> ' : ' ')
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
- buff << " {|#{args}|}"
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
- if (callee = b.eval('__callee__', __FILE__, __LINE__)) && (argc = iseq.argc) > 0
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
- buff << " #=> #{short_inspect(frame.return_value)}"
375
+ return_str = " #=> #{short_inspect(frame.return_value)}"
338
376
  end
339
377
  else
340
- # p frame.self
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
- buff
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 " # and #{size - max} frames (use `bt' command for all frames)" if max < size
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
@@ -1,3 +1,3 @@
1
1
  module DEBUGGER__
2
- VERSION = "1.0.0.beta2"
2
+ VERSION = "1.0.0.beta3"
3
3
  end
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.beta2
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-10 00:00:00.000000000 Z
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.