debug 1.0.0.rc1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +26 -14
- data/Rakefile +1 -1
- data/TODO.md +4 -8
- data/exe/rdbg +1 -1
- data/ext/debug/debug.c +5 -0
- data/lib/debug/breakpoint.rb +14 -5
- data/lib/debug/color.rb +2 -2
- data/lib/debug/config.rb +18 -3
- data/lib/debug/console.rb +10 -2
- data/lib/debug/frame_info.rb +2 -2
- data/lib/debug/local.rb +21 -24
- data/lib/debug/server.rb +8 -7
- data/lib/debug/server_dap.rb +15 -6
- data/lib/debug/session.rb +258 -99
- data/lib/debug/thread_client.rb +23 -14
- data/lib/debug/tracer.rb +8 -3
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +18 -11
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6eba8a00eaa711138e43036c5adb97834f1a87e586f8a5a3f580875e4d78e5c
|
4
|
+
data.tar.gz: 26ed8ac77bb93ab2a9f67fac6c4ef4481fbcdd227f116aaff78e808a2343b13b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b459267a95928388d1bf53bab8bf51fc8d5a6d0db0bc2fbaa55f740b1b446aad2294e45cc2b70471ccf8bb1daada458f239f08c7ceb7588774f08796a7838620
|
7
|
+
data.tar.gz: 86d06a4ec76943e26af39a26120c8a3a906d3fcecca195a662e63b9be2b7b9a1ba82bd2fba177205b436cde89be9214988e0f2cccc0f7fb2dcbf7226e92886e9
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ This debug.rb is replacement of traditional lib/debug.rb standard library which
|
|
8
8
|
New debug.rb has several advantages:
|
9
9
|
|
10
10
|
* Fast: No performance penalty on non-stepping mode and non-breakpoints.
|
11
|
-
* Remote debugging: Support remote debugging natively.
|
11
|
+
* [Remote debugging](#remote-debugging): Support remote debugging natively.
|
12
12
|
* UNIX domain socket
|
13
13
|
* TCP/IP
|
14
14
|
* VSCode/DAP integration ([VSCode rdbg Ruby Debugger - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg))
|
@@ -25,7 +25,7 @@ New debug.rb has several advantages:
|
|
25
25
|
# Installation
|
26
26
|
|
27
27
|
```
|
28
|
-
$ gem install debug
|
28
|
+
$ gem install debug
|
29
29
|
```
|
30
30
|
|
31
31
|
or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option, especially for debug this gem development.
|
@@ -33,7 +33,7 @@ or specify `-Ipath/to/debug/lib` in `RUBYOPT` or each ruby command-line option,
|
|
33
33
|
If you use Bundler, write the following line to your Gemfile.
|
34
34
|
|
35
35
|
```
|
36
|
-
gem "debug", ">= 1.0.0
|
36
|
+
gem "debug", ">= 1.0.0"
|
37
37
|
```
|
38
38
|
|
39
39
|
# HOW TO USE
|
@@ -44,22 +44,24 @@ To use a debugger, roughly you will do the following steps:
|
|
44
44
|
2. Run a program with the debugger.
|
45
45
|
3. At the breakpoint, enter the debugger console.
|
46
46
|
4. Use debug commands.
|
47
|
-
*
|
48
|
-
*
|
49
|
-
*
|
50
|
-
*
|
47
|
+
* [Evaluate Ruby expressions](#evaluate) (e.g. `p lvar` to see the local variable `lvar`).
|
48
|
+
* [Query the program status](#information) (e.g. `info` to see information about the current frame).
|
49
|
+
* [Control program flow](#control-flow) (e.g. move to the another line with `step`, to the next line with `next`).
|
50
|
+
* [Set another breakpoint](#breakpoint) (e.g. `catch Exception` to set a breakpoint that'll be triggered when `Exception` is raised).
|
51
|
+
* [Activate tracing in your program](#trace) (e.g. `trace call` to trace method calls).
|
52
|
+
* [Change the configuration](#configuration-1) (e.g. `config set no_color true` to disable coloring).
|
51
53
|
* Continue the program (`c` or `continue`) and goto 3.
|
52
54
|
|
53
55
|
## Invoke with the debugger
|
54
56
|
|
55
57
|
There are several options for (1) and (2). Please choose your favorite way.
|
56
58
|
|
57
|
-
### Modify source code
|
59
|
+
### Modify source code with [`binding.break`](#bindingbreak-method) (similar to `binding.pry` or `binding.irb`)
|
58
60
|
|
59
|
-
If you can modify the source code, you can use the debugger by adding `require 'debug'` line at the top of your program and putting `binding.break` method (`binding.b` for short) into lines where you want to stop as breakpoints like `binding.pry` and `binding.irb`.
|
61
|
+
If you can modify the source code, you can use the debugger by adding `require 'debug'` line at the top of your program and putting [`binding.break`](#bindingbreak-method) method (`binding.b` for short) into lines where you want to stop as breakpoints like `binding.pry` and `binding.irb`.
|
60
62
|
After that, you run the program as usual and you will enter the debug console at breakpoints you inserted.
|
61
63
|
|
62
|
-
The following example shows the demonstration of `binding.break
|
64
|
+
The following example shows the demonstration of [`binding.break`](#bindingbreak-method).
|
63
65
|
|
64
66
|
```shell
|
65
67
|
$ cat target.rb # Sample program
|
@@ -355,7 +357,7 @@ config set no_color true
|
|
355
357
|
* `RUBY_DEBUG_LOG_LEVEL` (`log_level`): Log level same as Logger (default: WARN)
|
356
358
|
* `RUBY_DEBUG_SHOW_SRC_LINES` (`show_src_lines`): Show n lines source code on breakpoint (default: 10 lines)
|
357
359
|
* `RUBY_DEBUG_SHOW_FRAMES` (`show_frames`): Show n frames on breakpoint (default: 2 frames)
|
358
|
-
* `RUBY_DEBUG_USE_SHORT_PATH` (`use_short_path`): Show
|
360
|
+
* `RUBY_DEBUG_USE_SHORT_PATH` (`use_short_path`): Show shorten PATH (like $(Gem)/foo.rb)
|
359
361
|
* `RUBY_DEBUG_NO_COLOR` (`no_color`): Do not use colorize (default: false)
|
360
362
|
* `RUBY_DEBUG_NO_SIGINT_HOOK` (`no_sigint_hook`): Do not suspend on SIGINT (default: false)
|
361
363
|
* `RUBY_DEBUG_NO_RELINE` (`no_reline`): Do not use Reline library (default: false)
|
@@ -370,6 +372,7 @@ config set no_color true
|
|
370
372
|
|
371
373
|
* BOOT
|
372
374
|
* `RUBY_DEBUG_NONSTOP` (`nonstop`): Nonstop mode
|
375
|
+
* `RUBY_DEBUG_STOP_AT_LOAD` (`stop_at_load`): Stop at just loading location
|
373
376
|
* `RUBY_DEBUG_INIT_SCRIPT` (`init_script`): debug command script path loaded at first stop
|
374
377
|
* `RUBY_DEBUG_COMMANDS` (`commands`): debug commands invoked at first stop. commands should be separated by ';;'
|
375
378
|
* `RUBY_DEBUG_NO_RC` (`no_rc`): ignore loading ~/.rdbgrc(.rb)
|
@@ -397,7 +400,12 @@ If there are `~/.rdbgrc.rb` is available, it is also loaded as a ruby script at
|
|
397
400
|
|
398
401
|
On the debug console, you can use the following debug commands.
|
399
402
|
|
400
|
-
|
403
|
+
There are additional features:
|
404
|
+
|
405
|
+
* `<expr>` without debug command is almost same as `pp <expr>`.
|
406
|
+
* If the input line `<expr>` does *NOT* start with any debug command, the line `<expr>` will be evaluated as a Ruby expression and the result will be printed with `pp` method. So that the input `foo.bar` is same as `pp foo.bar`.
|
407
|
+
* If `<expr>` is recognized as a debug command, of course it is not evaluated as a Ruby expression, but is executed as debug command. For example, you can not evaluate such single letter local variables `i`, `b`, `n`, `c` because they are single letter debug commands. Use `p i` instead.
|
408
|
+
* `Enter` without any input repeats the last command (useful when repeating `step`s).
|
401
409
|
* `Ctrl-D` is equal to `quit` command.
|
402
410
|
* [debug command compare sheet - Google Sheets](https://docs.google.com/spreadsheets/d/1TlmmUDsvwK4sSIyoMv-io52BUUz__R5wpu-ComXlsw0/edit?usp=sharing)
|
403
411
|
|
@@ -429,6 +437,9 @@ The `<...>` notation means the argument.
|
|
429
437
|
* Stop the debuggee process with `Kernal#exit!`.
|
430
438
|
* `kill!`
|
431
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`.
|
432
443
|
|
433
444
|
### Breakpoint
|
434
445
|
|
@@ -489,7 +500,7 @@ The `<...>` notation means the argument.
|
|
489
500
|
* Show information about the current frame (local variables)
|
490
501
|
* It includes `self` as `%self` and a return value as `%return`.
|
491
502
|
* `i[nfo] i[var[s]]` or `i[nfo] instance`
|
492
|
-
* Show information about
|
503
|
+
* Show information about instance variables about `self`.
|
493
504
|
* `i[nfo] c[onst[s]]` or `i[nfo] constant[s]`
|
494
505
|
* Show information about accessible constants except toplevel constants.
|
495
506
|
* `i[nfo] g[lobal[s]]`
|
@@ -529,7 +540,7 @@ The `<...>` notation means the argument.
|
|
529
540
|
* Evaluate like `p <expr>` on the current frame.
|
530
541
|
* `pp <expr>`
|
531
542
|
* Evaluate like `pp <expr>` on the current frame.
|
532
|
-
* `
|
543
|
+
* `eval <expr>`
|
533
544
|
* Evaluate `<expr>` on the current frame.
|
534
545
|
* `irb`
|
535
546
|
* Invoke `irb` on the current frame.
|
@@ -721,6 +732,7 @@ Attach mode:
|
|
721
732
|
Other options:
|
722
733
|
-h, --help Print help
|
723
734
|
--util=NAME Utility mode (used by tools)
|
735
|
+
--stop-at-load Stop immediately when the debugging feature is loaded.
|
724
736
|
|
725
737
|
NOTE
|
726
738
|
All messages communicated between a debugger and a debuggee are *NOT* encrypted.
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ Rake::ExtensionTask.new("debug") do |ext|
|
|
15
15
|
ext.lib_dir = "lib/debug"
|
16
16
|
end
|
17
17
|
|
18
|
-
task :default => [:clobber, :compile,
|
18
|
+
task :default => [:clobber, :compile, 'README.md', :test]
|
19
19
|
|
20
20
|
file 'README.md' => ['lib/debug/session.rb', 'lib/debug/config.rb',
|
21
21
|
'exe/rdbg', 'misc/README.md.erb'] do
|
data/TODO.md
CHANGED
@@ -3,25 +3,21 @@
|
|
3
3
|
## Basic functionality
|
4
4
|
|
5
5
|
* Support Ractors
|
6
|
-
* Signal (SIGINT)
|
6
|
+
* Signal (SIGINT) trap handling
|
7
7
|
|
8
8
|
## UI
|
9
9
|
|
10
|
+
* Completion for Ruby's code
|
10
11
|
* Interactive breakpoint setting
|
12
|
+
* Interactive record & play debugging
|
11
13
|
* irb integration
|
12
14
|
* Web browser integrated UI
|
15
|
+
* History file
|
13
16
|
|
14
17
|
## Debug command
|
15
18
|
|
16
19
|
* Breakpoints
|
17
20
|
* Lightweight pending method break points with Ruby 3.1 feature (TP:method_added)
|
18
|
-
* Non-stop breakpoint but runs some code.
|
19
21
|
* Watch points
|
20
22
|
* Lightweight watchpoints for instance variables with Ruby 3.1 features (TP:ivar_set)
|
21
23
|
* Faster `next`/`finish` command by specifying target code.
|
22
|
-
* `set`/`show` configurations
|
23
|
-
* In-memory line traces
|
24
|
-
* Timemachine debugging
|
25
|
-
|
26
|
-
## Tests
|
27
|
-
|
data/exe/rdbg
CHANGED
@@ -9,7 +9,7 @@ when :start
|
|
9
9
|
|
10
10
|
libpath = File.join(File.expand_path(File.dirname(__dir__)), 'lib/debug')
|
11
11
|
start_mode = config[:remote] ? "open" : 'start'
|
12
|
-
cmd = config[:command] ? ARGV.shift : RbConfig.ruby
|
12
|
+
cmd = config[:command] ? ARGV.shift : (ENV['RUBY'] || RbConfig.ruby)
|
13
13
|
|
14
14
|
env = ::DEBUGGER__::Config.config_to_env_hash(config)
|
15
15
|
env['RUBYOPT'] = "-r #{libpath}/#{start_mode}"
|
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,17 +431,24 @@ 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
|
-
rescue ArgumentError
|
440
|
+
rescue ArgumentError => e
|
437
441
|
raise if retried
|
438
442
|
retried = true
|
439
443
|
|
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
|
@@ -450,7 +458,7 @@ module DEBUGGER__
|
|
450
458
|
@override_method = true if @method
|
451
459
|
retry
|
452
460
|
end
|
453
|
-
rescue Exception
|
461
|
+
rescue Exception => e
|
454
462
|
raise unless added
|
455
463
|
end
|
456
464
|
|
@@ -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/color.rb
CHANGED
@@ -19,7 +19,7 @@ module DEBUGGER__
|
|
19
19
|
if defined? IRB::Color.colorize
|
20
20
|
def colorize str, color
|
21
21
|
if !CONFIG[:no_color]
|
22
|
-
IRB::Color.colorize str, color
|
22
|
+
IRB::Color.colorize str, color, colorable: true
|
23
23
|
else
|
24
24
|
str
|
25
25
|
end
|
@@ -64,7 +64,7 @@ module DEBUGGER__
|
|
64
64
|
|
65
65
|
if defined? IRB::Color.colorize_code
|
66
66
|
def colorize_code code
|
67
|
-
IRB::Color.colorize_code(code)
|
67
|
+
IRB::Color.colorize_code(code, colorable: true)
|
68
68
|
end
|
69
69
|
else
|
70
70
|
def colorize_code code
|
data/lib/debug/config.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DEBUGGER__
|
4
|
+
LOG_LEVELS = {
|
5
|
+
UNKNOWN: 0,
|
6
|
+
FATAL: 1,
|
7
|
+
ERROR: 2,
|
8
|
+
WARN: 3,
|
9
|
+
INFO: 4,
|
10
|
+
}.freeze
|
11
|
+
|
4
12
|
CONFIG_SET = {
|
5
13
|
# UI setting
|
6
14
|
log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger (default: WARN)", :loglevel],
|
7
15
|
show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint (default: 10 lines)", :int],
|
8
16
|
show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint (default: 2 frames)", :int],
|
9
|
-
use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show
|
17
|
+
use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool],
|
10
18
|
no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize (default: false)", :bool],
|
11
19
|
no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT (default: false)", :bool],
|
12
20
|
no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library (default: false)", :bool],
|
@@ -21,6 +29,7 @@ module DEBUGGER__
|
|
21
29
|
|
22
30
|
# boot setting
|
23
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],
|
24
33
|
init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
|
25
34
|
commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. commands should be separated by ';;'"],
|
26
35
|
no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool],
|
@@ -102,7 +111,9 @@ module DEBUGGER__
|
|
102
111
|
end
|
103
112
|
|
104
113
|
if_updated old_conf, conf, :postmortem do |_, new_p|
|
105
|
-
SESSION
|
114
|
+
if defined?(SESSION)
|
115
|
+
SESSION.postmortem = new_p
|
116
|
+
end
|
106
117
|
end
|
107
118
|
|
108
119
|
if_updated old_conf, conf, :sigdump_sig do |old_sig, new_sig|
|
@@ -306,6 +317,10 @@ module DEBUGGER__
|
|
306
317
|
exit
|
307
318
|
end
|
308
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
|
+
|
309
324
|
o.separator ''
|
310
325
|
o.separator 'NOTE'
|
311
326
|
o.separator ' All messages communicated between a debugger and a debuggee are *NOT* encrypted.'
|
@@ -372,7 +387,7 @@ module DEBUGGER__
|
|
372
387
|
desc = cat = nil
|
373
388
|
cmds = Hash.new
|
374
389
|
|
375
|
-
File.read(File.join(__dir__, 'session.rb')).each_line do |line|
|
390
|
+
File.read(File.join(__dir__, 'session.rb'), encoding: Encoding::UTF_8).each_line do |line|
|
376
391
|
case line
|
377
392
|
when /\A\s*### (.+)/
|
378
393
|
cat = $1
|
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
@@ -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
@@ -153,8 +153,8 @@ module DEBUGGER__
|
|
153
153
|
when 'setFunctionBreakpoints'
|
154
154
|
send_response req
|
155
155
|
when 'setExceptionBreakpoints'
|
156
|
-
|
157
|
-
case
|
156
|
+
process_filter = ->(filter_id) {
|
157
|
+
case filter_id
|
158
158
|
when 'any'
|
159
159
|
bp = SESSION.add_catch_breakpoint 'Exception'
|
160
160
|
when 'RuntimeError'
|
@@ -163,10 +163,19 @@ module DEBUGGER__
|
|
163
163
|
bp = nil
|
164
164
|
end
|
165
165
|
{
|
166
|
-
|
166
|
+
verified: bp ? true : false,
|
167
167
|
message: bp.inspect,
|
168
168
|
}
|
169
169
|
}
|
170
|
+
|
171
|
+
filters = args.fetch('filters').map {|filter_id|
|
172
|
+
process_filter.call(filter_id)
|
173
|
+
}
|
174
|
+
|
175
|
+
filters += args.fetch('filterOptions', {}).map{|bp_info|
|
176
|
+
process_filter.call(bp_info.dig('filterId'))
|
177
|
+
}
|
178
|
+
|
170
179
|
send_response req, breakpoints: filters
|
171
180
|
when 'configurationDone'
|
172
181
|
send_response req
|
@@ -354,7 +363,7 @@ module DEBUGGER__
|
|
354
363
|
fail_response req
|
355
364
|
end
|
356
365
|
else
|
357
|
-
raise "
|
366
|
+
raise "Unknown type: #{ref.inspect}"
|
358
367
|
end
|
359
368
|
else
|
360
369
|
fail_response req
|
@@ -471,7 +480,7 @@ module DEBUGGER__
|
|
471
480
|
fid = args.shift
|
472
481
|
frame = @target_frames[fid]
|
473
482
|
|
474
|
-
lnum =
|
483
|
+
lnum =
|
475
484
|
if frame.binding
|
476
485
|
frame.binding.local_variables.size
|
477
486
|
elsif vars = frame.local_variables
|
@@ -580,7 +589,7 @@ module DEBUGGER__
|
|
580
589
|
end
|
581
590
|
event! :dap_result, :evaluate, req, tid: self.id, **evaluate_result(result)
|
582
591
|
else
|
583
|
-
raise "
|
592
|
+
raise "Unknown req: #{args.inspect}"
|
584
593
|
end
|
585
594
|
end
|
586
595
|
|