debug 1.1.0 → 1.2.3
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/.github/ISSUE_TEMPLATE/bug_report.md +24 -0
- data/.github/ISSUE_TEMPLATE/custom.md +10 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- data/README.md +5 -0
- data/Rakefile +9 -6
- data/debug.gemspec +1 -1
- data/ext/debug/debug.c +5 -0
- data/lib/debug/breakpoint.rb +12 -3
- data/lib/debug/client.rb +33 -32
- data/lib/debug/color.rb +25 -3
- data/lib/debug/config.rb +26 -2
- data/lib/debug/console.rb +10 -2
- data/lib/debug/frame_info.rb +5 -5
- data/lib/debug/local.rb +21 -24
- data/lib/debug/server.rb +8 -7
- data/lib/debug/server_dap.rb +15 -13
- data/lib/debug/session.rb +206 -80
- data/lib/debug/thread_client.rb +22 -13
- data/lib/debug/tracer.rb +7 -2
- data/lib/debug/version.rb +1 -1
- metadata +11 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ebbeeac4c437bdefb9c0115008b705debb189b6332ee9ea056fd469c323c7149
|
|
4
|
+
data.tar.gz: 7a6abfb0490eaa49ec118efe89e50c51111be291a0b342fca930c3887a66aa72
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7bfb31a8b9b5fc882c20c28992ecdc501d4a11a8088023664ef2d590385e7ba3a8f756b92b74c607b0148e7e6710c213a14659ce8f33e10b261ee4031993582d
|
|
7
|
+
data.tar.gz: ad174799dd193021f845e971e08c19cc8c31bb915ee603659c33299c4a5e21d9bdf2e7687dfb1da75e0e573442fdc116b343d8caa7e54550ae62fbeea1ed6165
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Your environment**
|
|
11
|
+
|
|
12
|
+
* `ruby -v`:
|
|
13
|
+
* `rdbg -v`:
|
|
14
|
+
|
|
15
|
+
**Describe the bug**
|
|
16
|
+
A clear and concise description of what the bug is.
|
|
17
|
+
|
|
18
|
+
**To Reproduce**
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Additional context**
|
|
24
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Your proposal**
|
|
11
|
+
What is your idea?
|
|
12
|
+
|
|
13
|
+
**Additional context**
|
|
14
|
+
Add any other context or screenshots about the feature request here.
|
data/README.md
CHANGED
|
@@ -372,6 +372,7 @@ config set no_color true
|
|
|
372
372
|
|
|
373
373
|
* BOOT
|
|
374
374
|
* `RUBY_DEBUG_NONSTOP` (`nonstop`): Nonstop mode
|
|
375
|
+
* `RUBY_DEBUG_STOP_AT_LOAD` (`stop_at_load`): Stop at just loading location
|
|
375
376
|
* `RUBY_DEBUG_INIT_SCRIPT` (`init_script`): debug command script path loaded at first stop
|
|
376
377
|
* `RUBY_DEBUG_COMMANDS` (`commands`): debug commands invoked at first stop. commands should be separated by ';;'
|
|
377
378
|
* `RUBY_DEBUG_NO_RC` (`no_rc`): ignore loading ~/.rdbgrc(.rb)
|
|
@@ -436,6 +437,9 @@ The `<...>` notation means the argument.
|
|
|
436
437
|
* Stop the debuggee process with `Kernal#exit!`.
|
|
437
438
|
* `kill!`
|
|
438
439
|
* Same as kill but without the confirmation prompt.
|
|
440
|
+
* `sigint`
|
|
441
|
+
* Execute SIGINT handler registerred by the debuggee.
|
|
442
|
+
* Note that this command should be used just after stop by `SIGINT`.
|
|
439
443
|
|
|
440
444
|
### Breakpoint
|
|
441
445
|
|
|
@@ -728,6 +732,7 @@ Attach mode:
|
|
|
728
732
|
Other options:
|
|
729
733
|
-h, --help Print help
|
|
730
734
|
--util=NAME Utility mode (used by tools)
|
|
735
|
+
--stop-at-load Stop immediately when the debugging feature is loaded.
|
|
731
736
|
|
|
732
737
|
NOTE
|
|
733
738
|
All messages communicated between a debugger and a debuggee are *NOT* encrypted.
|
data/Rakefile
CHANGED
|
@@ -7,14 +7,17 @@ Rake::TestTask.new(:test) do |t|
|
|
|
7
7
|
t.test_files = FileList["test/**/*_test.rb"]
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
task :build => :compile
|
|
13
|
-
|
|
14
|
-
Rake::ExtensionTask.new("debug") do |ext|
|
|
15
|
-
|
|
10
|
+
begin
|
|
11
|
+
require "rake/extensiontask"
|
|
12
|
+
task :build => :compile
|
|
13
|
+
|
|
14
|
+
Rake::ExtensionTask.new("debug") do |ext|
|
|
15
|
+
ext.lib_dir = "lib/debug"
|
|
16
|
+
end
|
|
17
|
+
rescue LoadError
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
|
|
18
21
|
task :default => [:clobber, :compile, 'README.md', :test]
|
|
19
22
|
|
|
20
23
|
file 'README.md' => ['lib/debug/session.rb', 'lib/debug/config.rb',
|
data/debug.gemspec
CHANGED
|
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.require_paths = ["lib"]
|
|
26
26
|
spec.extensions = ['ext/debug/extconf.rb']
|
|
27
27
|
|
|
28
|
-
spec.add_dependency "irb" # for its color_printer class, which was added after 1.3
|
|
28
|
+
spec.add_dependency "irb", ">= 1.3.6" # for its color_printer class, which was added after 1.3
|
|
29
29
|
spec.add_dependency "reline", ">= 0.2.7"
|
|
30
30
|
end
|
data/ext/debug/debug.c
CHANGED
|
@@ -122,6 +122,11 @@ Init_debug(void)
|
|
|
122
122
|
{
|
|
123
123
|
rb_mDebugger = rb_const_get(rb_cObject, rb_intern("DEBUGGER__"));
|
|
124
124
|
rb_cFrameInfo = rb_const_get(rb_mDebugger, rb_intern("FrameInfo"));
|
|
125
|
+
|
|
126
|
+
// Debugger and FrameInfo were defined in Ruby. We need to register them
|
|
127
|
+
// as mark objects so they are automatically pinned.
|
|
128
|
+
rb_gc_register_mark_object(rb_mDebugger);
|
|
129
|
+
rb_gc_register_mark_object(rb_cFrameInfo);
|
|
125
130
|
rb_define_singleton_method(rb_mDebugger, "capture_frames", capture_frames, 1);
|
|
126
131
|
rb_define_singleton_method(rb_mDebugger, "frame_depth", frame_depth, 0);
|
|
127
132
|
rb_define_singleton_method(rb_mDebugger, "create_method_added_tracker", create_method_added_tracker, 0);
|
data/lib/debug/breakpoint.rb
CHANGED
|
@@ -288,6 +288,7 @@ module DEBUGGER__
|
|
|
288
288
|
@tp = TracePoint.new(:line){|tp|
|
|
289
289
|
next if tp.path.start_with? __dir__
|
|
290
290
|
next if tp.path.start_with? '<internal:'
|
|
291
|
+
next if ThreadClient.current.management?
|
|
291
292
|
|
|
292
293
|
if safe_eval tp.binding, @expr
|
|
293
294
|
suspend
|
|
@@ -430,7 +431,10 @@ module DEBUGGER__
|
|
|
430
431
|
if @sig_op == '#'
|
|
431
432
|
@cond_class = @klass if @method.owner != @klass
|
|
432
433
|
else # '.'
|
|
433
|
-
|
|
434
|
+
begin
|
|
435
|
+
@cond_class = @klass.singleton_class if @method.owner != @klass.singleton_class
|
|
436
|
+
rescue TypeError
|
|
437
|
+
end
|
|
434
438
|
end
|
|
435
439
|
|
|
436
440
|
rescue ArgumentError
|
|
@@ -440,7 +444,11 @@ module DEBUGGER__
|
|
|
440
444
|
# maybe C method
|
|
441
445
|
case @sig_op
|
|
442
446
|
when '.'
|
|
443
|
-
|
|
447
|
+
begin
|
|
448
|
+
override @klass.singleton_class
|
|
449
|
+
rescue TypeError
|
|
450
|
+
override @klass.class
|
|
451
|
+
end
|
|
444
452
|
when '#'
|
|
445
453
|
override @klass
|
|
446
454
|
end
|
|
@@ -460,7 +468,8 @@ module DEBUGGER__
|
|
|
460
468
|
|
|
461
469
|
def to_s
|
|
462
470
|
if @method
|
|
463
|
-
|
|
471
|
+
loc = @method.source_location || []
|
|
472
|
+
"#{generate_label("Method")} #{sig} at #{loc.join(':')}"
|
|
464
473
|
else
|
|
465
474
|
"#{generate_label("Method (pending)")} #{sig}"
|
|
466
475
|
end + super
|
data/lib/debug/client.rb
CHANGED
|
@@ -13,9 +13,37 @@ module DEBUGGER__
|
|
|
13
13
|
class CommandLineOptionError < Exception; end
|
|
14
14
|
|
|
15
15
|
class Client
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
class << self
|
|
17
|
+
def util name
|
|
18
|
+
case name
|
|
19
|
+
when 'gen-sockpath'
|
|
20
|
+
puts DEBUGGER__.create_unix_domain_socket_name
|
|
21
|
+
when 'list-socks'
|
|
22
|
+
cleanup_unix_domain_sockets
|
|
23
|
+
puts list_connections
|
|
24
|
+
else
|
|
25
|
+
raise "Unknown utility: #{name}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
18
28
|
|
|
29
|
+
def cleanup_unix_domain_sockets
|
|
30
|
+
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
|
|
31
|
+
if /(\d+)$/ =~ file
|
|
32
|
+
begin
|
|
33
|
+
Process.kill(0, $1.to_i)
|
|
34
|
+
rescue Errno::ESRCH
|
|
35
|
+
File.unlink(file)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def list_connections
|
|
42
|
+
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize argv
|
|
19
47
|
@console = Console.new
|
|
20
48
|
|
|
21
49
|
case argv.size
|
|
@@ -48,34 +76,6 @@ module DEBUGGER__
|
|
|
48
76
|
@console.readline "(rdbg:remote) "
|
|
49
77
|
end
|
|
50
78
|
|
|
51
|
-
def util name
|
|
52
|
-
case name
|
|
53
|
-
when 'gen-sockpath'
|
|
54
|
-
puts DEBUGGER__.create_unix_domain_socket_name
|
|
55
|
-
when 'list-socks'
|
|
56
|
-
cleanup_unix_domain_sockets
|
|
57
|
-
puts list_connections
|
|
58
|
-
else
|
|
59
|
-
raise "Unknown utility: #{name}"
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def cleanup_unix_domain_sockets
|
|
64
|
-
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
|
|
65
|
-
if /(\d+)$/ =~ file
|
|
66
|
-
begin
|
|
67
|
-
Process.kill(0, $1.to_i)
|
|
68
|
-
rescue Errno::ESRCH
|
|
69
|
-
File.unlink(file)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def list_connections
|
|
76
|
-
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
|
|
77
|
-
end
|
|
78
|
-
|
|
79
79
|
def connect_unix name = nil
|
|
80
80
|
if name
|
|
81
81
|
if File.exist? name
|
|
@@ -84,8 +84,9 @@ module DEBUGGER__
|
|
|
84
84
|
@s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_dir, name))
|
|
85
85
|
end
|
|
86
86
|
else
|
|
87
|
-
cleanup_unix_domain_sockets
|
|
88
|
-
files = list_connections
|
|
87
|
+
Client.cleanup_unix_domain_sockets
|
|
88
|
+
files = Client.list_connections
|
|
89
|
+
|
|
89
90
|
case files.size
|
|
90
91
|
when 0
|
|
91
92
|
$stderr.puts "No debug session is available."
|
data/lib/debug/color.rb
CHANGED
|
@@ -17,9 +17,25 @@ end
|
|
|
17
17
|
module DEBUGGER__
|
|
18
18
|
module Color
|
|
19
19
|
if defined? IRB::Color.colorize
|
|
20
|
+
begin
|
|
21
|
+
IRB::Color.colorize('', [:DIM], colorable: true)
|
|
22
|
+
SUPPORT_COLORABLE_OPTION = true
|
|
23
|
+
rescue ArgumentError
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if defined? SUPPORT_COLORABLE_OPTION
|
|
27
|
+
def irb_colorize str, color
|
|
28
|
+
IRB::Color.colorize str, color, colorable: true
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
def irb_colorize str, color
|
|
32
|
+
IRB::Color.colorize str, color
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
20
36
|
def colorize str, color
|
|
21
37
|
if !CONFIG[:no_color]
|
|
22
|
-
|
|
38
|
+
irb_colorize str, color
|
|
23
39
|
else
|
|
24
40
|
str
|
|
25
41
|
end
|
|
@@ -63,8 +79,14 @@ module DEBUGGER__
|
|
|
63
79
|
end
|
|
64
80
|
|
|
65
81
|
if defined? IRB::Color.colorize_code
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
if SUPPORT_COLORABLE_OPTION
|
|
83
|
+
def colorize_code code
|
|
84
|
+
IRB::Color.colorize_code(code, colorable: true)
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
def colorize_code code
|
|
88
|
+
IRB::Color.colorize_code(code)
|
|
89
|
+
end
|
|
68
90
|
end
|
|
69
91
|
else
|
|
70
92
|
def colorize_code code
|
data/lib/debug/config.rb
CHANGED
|
@@ -29,6 +29,7 @@ module DEBUGGER__
|
|
|
29
29
|
|
|
30
30
|
# boot setting
|
|
31
31
|
nonstop: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool],
|
|
32
|
+
stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool],
|
|
32
33
|
init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
|
|
33
34
|
commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. commands should be separated by ';;'"],
|
|
34
35
|
no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool],
|
|
@@ -110,7 +111,9 @@ module DEBUGGER__
|
|
|
110
111
|
end
|
|
111
112
|
|
|
112
113
|
if_updated old_conf, conf, :postmortem do |_, new_p|
|
|
113
|
-
SESSION
|
|
114
|
+
if defined?(SESSION)
|
|
115
|
+
SESSION.postmortem = new_p
|
|
116
|
+
end
|
|
114
117
|
end
|
|
115
118
|
|
|
116
119
|
if_updated old_conf, conf, :sigdump_sig do |old_sig, new_sig|
|
|
@@ -310,10 +313,14 @@ module DEBUGGER__
|
|
|
310
313
|
|
|
311
314
|
o.on('--util=NAME', 'Utility mode (used by tools)') do |name|
|
|
312
315
|
require_relative 'client'
|
|
313
|
-
Client.
|
|
316
|
+
Client.util(name)
|
|
314
317
|
exit
|
|
315
318
|
end
|
|
316
319
|
|
|
320
|
+
o.on('--stop-at-load', 'Stop immediately when the debugging feature is loaded.') do
|
|
321
|
+
config[:stop_at_load] = true
|
|
322
|
+
end
|
|
323
|
+
|
|
317
324
|
o.separator ''
|
|
318
325
|
o.separator 'NOTE'
|
|
319
326
|
o.separator ' All messages communicated between a debugger and a debuggee are *NOT* encrypted.'
|
|
@@ -345,9 +352,26 @@ module DEBUGGER__
|
|
|
345
352
|
## Unix domain socket configuration
|
|
346
353
|
|
|
347
354
|
def self.unix_domain_socket_dir
|
|
355
|
+
require 'tmpdir'
|
|
356
|
+
|
|
348
357
|
case
|
|
349
358
|
when path = CONFIG[:sock_dir]
|
|
350
359
|
when path = ENV['XDG_RUNTIME_DIR']
|
|
360
|
+
when tmpdir = Dir.tmpdir
|
|
361
|
+
path = File.join(tmpdir, "ruby-debug-sock-#{Process.uid}")
|
|
362
|
+
|
|
363
|
+
if File.exist?(path)
|
|
364
|
+
fs = File.stat(path)
|
|
365
|
+
unless (dir_uid = fs.uid) == (uid = Process.uid)
|
|
366
|
+
raise "#{path} uid is #{dir_uid}, but Process.uid is #{uid}"
|
|
367
|
+
end
|
|
368
|
+
unless (dir_mode = fs.mode) == 040700 # 4: dir, 7:rwx
|
|
369
|
+
raise "#{path}'s mode is #{dir_mode.to_s(8)} (should be 040700)"
|
|
370
|
+
end
|
|
371
|
+
else
|
|
372
|
+
d = Dir.mktmpdir
|
|
373
|
+
File.rename(d, path)
|
|
374
|
+
end
|
|
351
375
|
when home = ENV['HOME']
|
|
352
376
|
path = File.join(home, '.ruby-debug-sock')
|
|
353
377
|
|
data/lib/debug/console.rb
CHANGED
|
@@ -6,11 +6,19 @@ module DEBUGGER__
|
|
|
6
6
|
require 'reline'
|
|
7
7
|
|
|
8
8
|
# reline 0.2.7 or later is required.
|
|
9
|
-
raise LoadError if Reline::VERSION < '0.2.
|
|
9
|
+
raise LoadError if Reline::VERSION < '0.2.7'
|
|
10
10
|
|
|
11
11
|
require_relative 'color'
|
|
12
12
|
include Color
|
|
13
13
|
|
|
14
|
+
begin
|
|
15
|
+
prev = trap(:SIGWINCH, nil)
|
|
16
|
+
trap(:SIGWINCH, prev)
|
|
17
|
+
SIGWINCH_SUPPORTED = true
|
|
18
|
+
rescue ArgumentError
|
|
19
|
+
SIGWINCH_SUPPORTED = false
|
|
20
|
+
end
|
|
21
|
+
|
|
14
22
|
# 0.2.7 has SIGWINCH issue on non-main thread
|
|
15
23
|
class ::Reline::LineEditor
|
|
16
24
|
m = Module.new do
|
|
@@ -20,7 +28,7 @@ module DEBUGGER__
|
|
|
20
28
|
end
|
|
21
29
|
end
|
|
22
30
|
prepend m
|
|
23
|
-
end
|
|
31
|
+
end if SIGWINCH_SUPPORTED
|
|
24
32
|
|
|
25
33
|
def readline_setup prompt
|
|
26
34
|
commands = DEBUGGER__.commands
|
data/lib/debug/frame_info.rb
CHANGED
|
@@ -9,10 +9,10 @@ module DEBUGGER__
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
# extend FrameInfo with debug.so
|
|
12
|
-
|
|
12
|
+
begin
|
|
13
13
|
require_relative 'debug.so'
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
rescue LoadError
|
|
15
|
+
require 'debug/debug.so'
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
class FrameInfo
|
|
@@ -27,6 +27,7 @@ module DEBUGGER__
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def pretty_path
|
|
30
|
+
return '#<none>' unless path = self.path
|
|
30
31
|
use_short_path = CONFIG[:use_short_path]
|
|
31
32
|
|
|
32
33
|
case
|
|
@@ -137,10 +138,9 @@ module DEBUGGER__
|
|
|
137
138
|
if lvars = self._local_variables
|
|
138
139
|
lvars
|
|
139
140
|
elsif b = self.binding
|
|
140
|
-
|
|
141
|
+
b.local_variables.map{|var|
|
|
141
142
|
[var, b.local_variable_get(var)]
|
|
142
143
|
}.to_h
|
|
143
|
-
self._local_variables = lvars
|
|
144
144
|
end
|
|
145
145
|
end
|
|
146
146
|
|
data/lib/debug/local.rb
CHANGED
|
@@ -7,32 +7,27 @@ module DEBUGGER__
|
|
|
7
7
|
class UI_LocalConsole < UI_Base
|
|
8
8
|
def initialize
|
|
9
9
|
@console = Console.new
|
|
10
|
-
|
|
11
|
-
unless CONFIG[:no_sigint_hook]
|
|
12
|
-
@prev_handler = trap(:SIGINT){
|
|
13
|
-
if SESSION.active?
|
|
14
|
-
ThreadClient.current.on_trap :SIGINT
|
|
15
|
-
end
|
|
16
|
-
}
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def close
|
|
21
|
-
if @prev_handler
|
|
22
|
-
trap(:SIGINT, @prev_handler)
|
|
23
|
-
end
|
|
24
10
|
end
|
|
25
11
|
|
|
26
12
|
def remote?
|
|
27
13
|
false
|
|
28
14
|
end
|
|
29
15
|
|
|
30
|
-
def activate on_fork: false
|
|
31
|
-
|
|
16
|
+
def activate session, on_fork: false
|
|
17
|
+
unless CONFIG[:no_sigint_hook]
|
|
18
|
+
prev_handler = trap(:SIGINT){
|
|
19
|
+
if session.active?
|
|
20
|
+
ThreadClient.current.on_trap :SIGINT
|
|
21
|
+
end
|
|
22
|
+
}
|
|
23
|
+
session.intercept_trap_sigint_start prev_handler
|
|
24
|
+
end
|
|
32
25
|
end
|
|
33
26
|
|
|
34
27
|
def deactivate
|
|
35
|
-
|
|
28
|
+
if SESSION.intercept_trap_sigint?
|
|
29
|
+
trap(:SIGINT, SESSION.intercepted_sigint_cmd)
|
|
30
|
+
end
|
|
36
31
|
end
|
|
37
32
|
|
|
38
33
|
def width
|
|
@@ -76,15 +71,17 @@ module DEBUGGER__
|
|
|
76
71
|
end
|
|
77
72
|
|
|
78
73
|
def setup_interrupt
|
|
79
|
-
|
|
74
|
+
SESSION.intercept_trap_sigint false do
|
|
75
|
+
current_thread = Thread.current # should be session_server thread
|
|
80
76
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
prev_handler = trap(:INT){
|
|
78
|
+
current_thread.raise Interrupt
|
|
79
|
+
}
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
yield
|
|
82
|
+
ensure
|
|
83
|
+
trap(:INT, prev_handler)
|
|
84
|
+
end
|
|
88
85
|
end
|
|
89
86
|
end
|
|
90
87
|
end
|
data/lib/debug/server.rb
CHANGED
|
@@ -15,8 +15,6 @@ module DEBUGGER__
|
|
|
15
15
|
@q_ans = nil
|
|
16
16
|
@unsent_messages = []
|
|
17
17
|
@width = 80
|
|
18
|
-
|
|
19
|
-
activate
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
class Terminate < StandardError
|
|
@@ -37,7 +35,7 @@ module DEBUGGER__
|
|
|
37
35
|
end
|
|
38
36
|
end
|
|
39
37
|
|
|
40
|
-
def activate on_fork: false
|
|
38
|
+
def activate session, on_fork: false
|
|
41
39
|
@reader_thread = Thread.new do
|
|
42
40
|
# An error on this thread should break the system.
|
|
43
41
|
Thread.current.abort_on_exception = true
|
|
@@ -138,9 +136,9 @@ module DEBUGGER__
|
|
|
138
136
|
end
|
|
139
137
|
|
|
140
138
|
def setup_interrupt
|
|
141
|
-
prev_handler = trap(:
|
|
139
|
+
prev_handler = trap(:SIGURG) do
|
|
142
140
|
# $stderr.puts "trapped SIGINT"
|
|
143
|
-
ThreadClient.current.on_trap :
|
|
141
|
+
ThreadClient.current.on_trap :SIGURG
|
|
144
142
|
|
|
145
143
|
case prev_handler
|
|
146
144
|
when Proc
|
|
@@ -150,9 +148,12 @@ module DEBUGGER__
|
|
|
150
148
|
end
|
|
151
149
|
end
|
|
152
150
|
|
|
151
|
+
if prev_handler != "SYSTEM_DEFAULT"
|
|
152
|
+
DEBUGGER__.warn "SIGURG handler is overriddend by the debugger."
|
|
153
|
+
end
|
|
153
154
|
yield
|
|
154
155
|
ensure
|
|
155
|
-
trap(:
|
|
156
|
+
trap(:SIGURG, prev_handler)
|
|
156
157
|
end
|
|
157
158
|
|
|
158
159
|
attr_reader :reader_thread
|
|
@@ -230,7 +231,7 @@ module DEBUGGER__
|
|
|
230
231
|
|
|
231
232
|
def pause
|
|
232
233
|
# $stderr.puts "DEBUG: pause request"
|
|
233
|
-
Process.kill(:
|
|
234
|
+
Process.kill(:SIGURG, Process.pid)
|
|
234
235
|
end
|
|
235
236
|
|
|
236
237
|
def quit n
|
data/lib/debug/server_dap.rb
CHANGED
|
@@ -182,7 +182,7 @@ module DEBUGGER__
|
|
|
182
182
|
@q_msg << 'continue'
|
|
183
183
|
when 'attach'
|
|
184
184
|
send_response req
|
|
185
|
-
Process.kill(:
|
|
185
|
+
Process.kill(:SIGURG, Process.pid)
|
|
186
186
|
when 'disconnect'
|
|
187
187
|
send_response req
|
|
188
188
|
@q_msg << 'continue'
|
|
@@ -205,7 +205,7 @@ module DEBUGGER__
|
|
|
205
205
|
exit
|
|
206
206
|
when 'pause'
|
|
207
207
|
send_response req
|
|
208
|
-
Process.kill(:
|
|
208
|
+
Process.kill(:SIGURG, Process.pid)
|
|
209
209
|
when 'reverseContinue'
|
|
210
210
|
send_response req,
|
|
211
211
|
success: false, message: 'cancelled',
|
|
@@ -256,7 +256,7 @@ module DEBUGGER__
|
|
|
256
256
|
def event type, *args
|
|
257
257
|
case type
|
|
258
258
|
when :suspend_bp
|
|
259
|
-
_i, bp = *args
|
|
259
|
+
_i, bp, tid = *args
|
|
260
260
|
if bp.kind_of?(CatchBreakpoint)
|
|
261
261
|
reason = 'exception'
|
|
262
262
|
text = bp.description
|
|
@@ -268,24 +268,26 @@ module DEBUGGER__
|
|
|
268
268
|
send_event 'stopped', reason: reason,
|
|
269
269
|
description: text,
|
|
270
270
|
text: text,
|
|
271
|
-
threadId:
|
|
271
|
+
threadId: tid,
|
|
272
272
|
allThreadsStopped: true
|
|
273
273
|
when :suspend_trap
|
|
274
|
+
_sig, tid = *args
|
|
274
275
|
send_event 'stopped', reason: 'pause',
|
|
275
|
-
threadId:
|
|
276
|
+
threadId: tid,
|
|
276
277
|
allThreadsStopped: true
|
|
277
278
|
when :suspended
|
|
279
|
+
tid, = *args
|
|
278
280
|
send_event 'stopped', reason: 'step',
|
|
279
|
-
threadId:
|
|
281
|
+
threadId: tid,
|
|
280
282
|
allThreadsStopped: true
|
|
281
283
|
end
|
|
282
284
|
end
|
|
283
285
|
end
|
|
284
286
|
|
|
285
287
|
class Session
|
|
286
|
-
def
|
|
288
|
+
def find_waiting_tc id
|
|
287
289
|
@th_clients.each{|th, tc|
|
|
288
|
-
return tc if tc.id == id
|
|
290
|
+
return tc if tc.id == id && tc.waiting?
|
|
289
291
|
}
|
|
290
292
|
return nil
|
|
291
293
|
end
|
|
@@ -306,7 +308,7 @@ module DEBUGGER__
|
|
|
306
308
|
|
|
307
309
|
when 'stackTrace'
|
|
308
310
|
tid = req.dig('arguments', 'threadId')
|
|
309
|
-
if tc =
|
|
311
|
+
if tc = find_waiting_tc(tid)
|
|
310
312
|
tc << [:dap, :backtrace, req]
|
|
311
313
|
else
|
|
312
314
|
fail_response req
|
|
@@ -315,7 +317,7 @@ module DEBUGGER__
|
|
|
315
317
|
frame_id = req.dig('arguments', 'frameId')
|
|
316
318
|
if @frame_map[frame_id]
|
|
317
319
|
tid, fid = @frame_map[frame_id]
|
|
318
|
-
if tc =
|
|
320
|
+
if tc = find_waiting_tc(tid)
|
|
319
321
|
tc << [:dap, :scopes, req, fid]
|
|
320
322
|
else
|
|
321
323
|
fail_response req
|
|
@@ -348,7 +350,7 @@ module DEBUGGER__
|
|
|
348
350
|
frame_id = ref[1]
|
|
349
351
|
tid, fid = @frame_map[frame_id]
|
|
350
352
|
|
|
351
|
-
if tc =
|
|
353
|
+
if tc = find_waiting_tc(tid)
|
|
352
354
|
tc << [:dap, :scope, req, fid]
|
|
353
355
|
else
|
|
354
356
|
fail_response req
|
|
@@ -357,7 +359,7 @@ module DEBUGGER__
|
|
|
357
359
|
when :variable
|
|
358
360
|
tid, vid = ref[1], ref[2]
|
|
359
361
|
|
|
360
|
-
if tc =
|
|
362
|
+
if tc = find_waiting_tc(tid)
|
|
361
363
|
tc << [:dap, :variable, req, vid]
|
|
362
364
|
else
|
|
363
365
|
fail_response req
|
|
@@ -373,7 +375,7 @@ module DEBUGGER__
|
|
|
373
375
|
if @frame_map[frame_id]
|
|
374
376
|
tid, fid = @frame_map[frame_id]
|
|
375
377
|
expr = req.dig('arguments', 'expression')
|
|
376
|
-
if tc =
|
|
378
|
+
if tc = find_waiting_tc(tid)
|
|
377
379
|
tc << [:dap, :evaluate, req, fid, expr]
|
|
378
380
|
else
|
|
379
381
|
fail_response req
|