debug 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +79 -11
- data/README.md +39 -16
- data/Rakefile +25 -7
- data/debug.gemspec +1 -1
- data/exe/rdbg +7 -3
- data/ext/debug/debug.c +0 -22
- data/ext/debug/extconf.rb +18 -7
- data/lib/debug/breakpoint.rb +68 -33
- data/lib/debug/client.rb +12 -2
- data/lib/debug/config.rb +55 -24
- data/lib/debug/console.rb +9 -3
- data/lib/debug/frame_info.rb +31 -24
- data/lib/debug/server.rb +44 -17
- data/lib/debug/server_cdp.rb +5 -5
- data/lib/debug/server_dap.rb +221 -115
- data/lib/debug/session.rb +227 -129
- data/lib/debug/source_repository.rb +13 -0
- data/lib/debug/thread_client.rb +161 -64
- data/lib/debug/tracer.rb +4 -3
- data/lib/debug/version.rb +1 -1
- data/misc/README.md.erb +28 -8
- metadata +5 -6
- data/lib/debug/bp.vim +0 -68
data/lib/debug/config.rb
CHANGED
@@ -7,46 +7,50 @@ module DEBUGGER__
|
|
7
7
|
ERROR: 2,
|
8
8
|
WARN: 3,
|
9
9
|
INFO: 4,
|
10
|
+
DEBUG: 5
|
10
11
|
}.freeze
|
11
12
|
|
12
13
|
CONFIG_SET = {
|
13
14
|
# UI setting
|
14
|
-
log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger
|
15
|
-
show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint
|
16
|
-
show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint
|
17
|
-
use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)",
|
18
|
-
no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize
|
19
|
-
no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT
|
20
|
-
no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library
|
15
|
+
log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger", :loglevel, "WARN"],
|
16
|
+
show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint", :int, "10"],
|
17
|
+
show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint", :int, "2"],
|
18
|
+
use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool, "false"],
|
19
|
+
no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize", :bool, "false"],
|
20
|
+
no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT", :bool, "false"],
|
21
|
+
no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library", :bool, "false"],
|
22
|
+
no_hint: ['RUBY_DEBUG_NO_HINT', "UI: Do not show the hint on the REPL", :bool, "false"],
|
21
23
|
|
22
24
|
# control setting
|
23
|
-
skip_path: ['RUBY_DEBUG_SKIP_PATH', "CONTROL: Skip showing/entering frames for given paths
|
24
|
-
skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines
|
25
|
-
keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it
|
26
|
-
postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug
|
27
|
-
fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child)
|
28
|
-
sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal
|
25
|
+
skip_path: ['RUBY_DEBUG_SKIP_PATH', "CONTROL: Skip showing/entering frames for given paths", :path],
|
26
|
+
skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines", :bool, "false"],
|
27
|
+
keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it", :bool, "false"],
|
28
|
+
postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug", :bool, "false"],
|
29
|
+
fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child)", :forkmode, "both"],
|
30
|
+
sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal", :bool, "false"],
|
29
31
|
|
30
32
|
# boot setting
|
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],
|
33
|
+
nonstop: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool, "false"],
|
34
|
+
stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool, "false"],
|
33
35
|
init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
|
34
36
|
commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. commands should be separated by ';;'"],
|
35
|
-
no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool],
|
36
|
-
history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file
|
37
|
-
save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines
|
37
|
+
no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool, "false"],
|
38
|
+
history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file", :string, "~/.rdbg_history"],
|
39
|
+
save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines", :int, "10000"],
|
38
40
|
|
39
41
|
# remote setting
|
40
42
|
port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"],
|
41
|
-
host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host
|
43
|
+
host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"],
|
42
44
|
sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
|
43
45
|
sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
|
46
|
+
local_fs_map: ['RUBY_DEBUG_LOCAL_FS_MAP', "REMOTE: Specify local fs map", :path_map],
|
47
|
+
skip_bp: ['RUBY_DEBUG_SKIP_BP', "REMOTE: Skip breakpoints if no clients are attached", :bool, 'false'],
|
44
48
|
cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
|
45
49
|
open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
|
46
50
|
chrome_path: ['RUBY_DEBUG_CHROME_PATH', "REMOTE: Platform dependent path of Chrome (For more information, See [here](https://github.com/ruby/debug/pull/334/files#diff-5fc3d0a901379a95bc111b86cf0090b03f857edfd0b99a0c1537e26735698453R55-R64))"],
|
47
51
|
|
48
52
|
# obsolete
|
49
|
-
parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork
|
53
|
+
parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork", :bool, "false"],
|
50
54
|
}.freeze
|
51
55
|
|
52
56
|
CONFIG_MAP = CONFIG_SET.map{|k, (ev, _)| [k, ev]}.to_h.freeze
|
@@ -59,11 +63,23 @@ module DEBUGGER__
|
|
59
63
|
end
|
60
64
|
|
61
65
|
def initialize argv
|
66
|
+
@skip_all = false
|
67
|
+
|
62
68
|
if self.class.config
|
63
69
|
raise 'Can not make multiple configurations in one process'
|
64
70
|
end
|
65
71
|
|
66
|
-
|
72
|
+
config = self.class.parse_argv(argv)
|
73
|
+
|
74
|
+
# apply defaults
|
75
|
+
CONFIG_SET.each do |k, config_detail|
|
76
|
+
unless config.key?(k)
|
77
|
+
default_value = config_detail[3]
|
78
|
+
config[k] = parse_config_value(k, default_value)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
update config
|
67
83
|
end
|
68
84
|
|
69
85
|
def inspect
|
@@ -78,6 +94,14 @@ module DEBUGGER__
|
|
78
94
|
set_config(key => val)
|
79
95
|
end
|
80
96
|
|
97
|
+
def skip_all
|
98
|
+
@skip_all = true
|
99
|
+
end
|
100
|
+
|
101
|
+
def skip?
|
102
|
+
@skip_all
|
103
|
+
end
|
104
|
+
|
81
105
|
def set_config(**kw)
|
82
106
|
conf = config.dup
|
83
107
|
kw.each{|k, v|
|
@@ -114,11 +138,13 @@ module DEBUGGER__
|
|
114
138
|
self.class.instance_variable_set(:@config, conf.freeze)
|
115
139
|
|
116
140
|
# Post process
|
117
|
-
if_updated old_conf, conf, :keep_alloc_site do |
|
141
|
+
if_updated old_conf, conf, :keep_alloc_site do |old, new|
|
118
142
|
if new
|
119
143
|
require 'objspace'
|
120
144
|
ObjectSpace.trace_object_allocations_start
|
121
|
-
|
145
|
+
end
|
146
|
+
|
147
|
+
if old && !new
|
122
148
|
ObjectSpace.trace_object_allocations_stop
|
123
149
|
end
|
124
150
|
end
|
@@ -215,6 +241,8 @@ module DEBUGGER__
|
|
215
241
|
e
|
216
242
|
end
|
217
243
|
}
|
244
|
+
when :path_map
|
245
|
+
valstr.split(',').map{|e| e.split(':')}
|
218
246
|
else
|
219
247
|
valstr
|
220
248
|
end
|
@@ -223,6 +251,7 @@ module DEBUGGER__
|
|
223
251
|
def self.parse_argv argv
|
224
252
|
config = {
|
225
253
|
mode: :start,
|
254
|
+
no_color: (nc = ENV['NO_COLOR']) && !nc.empty?,
|
226
255
|
}
|
227
256
|
CONFIG_MAP.each{|key, evname|
|
228
257
|
if val = ENV[evname]
|
@@ -361,6 +390,8 @@ module DEBUGGER__
|
|
361
390
|
case CONFIG_SET[key][2]
|
362
391
|
when :path
|
363
392
|
valstr = config[key].map{|e| e.kind_of?(Regexp) ? e.inspect : e}.join(':')
|
393
|
+
when :path_map
|
394
|
+
valstr = config[key].map{|e| e.join(':')}.join(',')
|
364
395
|
else
|
365
396
|
valstr = config[key].to_s
|
366
397
|
end
|
@@ -428,7 +459,7 @@ module DEBUGGER__
|
|
428
459
|
end
|
429
460
|
|
430
461
|
def self.create_unix_domain_socket_name_prefix(base_dir = unix_domain_socket_dir)
|
431
|
-
user = ENV['USER'] || '
|
462
|
+
user = ENV['USER'] || 'UnknownUser'
|
432
463
|
File.join(base_dir, "ruby-debug-#{user}")
|
433
464
|
end
|
434
465
|
|
data/lib/debug/console.rb
CHANGED
@@ -98,7 +98,7 @@ module DEBUGGER__
|
|
98
98
|
when :ruby
|
99
99
|
colorize_code(buff.chomp)
|
100
100
|
end
|
101
|
-
end
|
101
|
+
end unless CONFIG[:no_hint]
|
102
102
|
|
103
103
|
yield
|
104
104
|
|
@@ -174,7 +174,13 @@ module DEBUGGER__
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def history_file
|
177
|
-
CONFIG[:history_file]
|
177
|
+
history_file = CONFIG[:history_file]
|
178
|
+
|
179
|
+
if !history_file.empty?
|
180
|
+
File.expand_path(history_file)
|
181
|
+
else
|
182
|
+
history_file
|
183
|
+
end
|
178
184
|
end
|
179
185
|
|
180
186
|
FH = "# Today's OMIKUJI: "
|
@@ -202,7 +208,7 @@ module DEBUGGER__
|
|
202
208
|
if history && @init_history_lines
|
203
209
|
added_records = history.to_a[@init_history_lines .. -1]
|
204
210
|
path = history_file
|
205
|
-
max = CONFIG[:save_history]
|
211
|
+
max = CONFIG[:save_history]
|
206
212
|
|
207
213
|
if !added_records.empty? && !path.empty?
|
208
214
|
orig_records = read_history_file
|
data/lib/debug/frame_info.rb
CHANGED
@@ -27,8 +27,8 @@ module DEBUGGER__
|
|
27
27
|
location.absolute_path
|
28
28
|
end
|
29
29
|
|
30
|
-
def pretty_path
|
31
|
-
return '#<none>' unless path
|
30
|
+
def self.pretty_path path
|
31
|
+
return '#<none>' unless path
|
32
32
|
use_short_path = CONFIG[:use_short_path]
|
33
33
|
|
34
34
|
case
|
@@ -45,15 +45,18 @@ module DEBUGGER__
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
def pretty_path
|
49
|
+
FrameInfo.pretty_path path
|
50
|
+
end
|
51
|
+
|
48
52
|
def name
|
49
53
|
# p frame_type: frame_type, self: self
|
50
54
|
case frame_type
|
51
55
|
when :block
|
52
|
-
level, block_loc
|
56
|
+
level, block_loc = block_identifier
|
53
57
|
"block in #{block_loc}#{level}"
|
54
58
|
when :method
|
55
|
-
|
56
|
-
"#{ci}"
|
59
|
+
method_identifier
|
57
60
|
when :c
|
58
61
|
c_identifier
|
59
62
|
when :other
|
@@ -83,16 +86,13 @@ module DEBUGGER__
|
|
83
86
|
|
84
87
|
def block_identifier
|
85
88
|
return unless frame_type == :block
|
86
|
-
args = parameters_info
|
87
89
|
_, level, block_loc = location.label.match(BLOCK_LABL_REGEXP).to_a
|
88
|
-
[level || "", block_loc
|
90
|
+
[level || "", block_loc]
|
89
91
|
end
|
90
92
|
|
91
93
|
def method_identifier
|
92
94
|
return unless frame_type == :method
|
93
|
-
|
94
|
-
ci = "#{klass_sig}#{callee}"
|
95
|
-
[ci, args]
|
95
|
+
"#{klass_sig}#{callee}"
|
96
96
|
end
|
97
97
|
|
98
98
|
def c_identifier
|
@@ -106,7 +106,11 @@ module DEBUGGER__
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def callee
|
109
|
-
self._callee ||=
|
109
|
+
self._callee ||= begin
|
110
|
+
self.binding&.eval('__callee__')
|
111
|
+
rescue NameError # BasicObject
|
112
|
+
nil
|
113
|
+
end
|
110
114
|
end
|
111
115
|
|
112
116
|
def return_str
|
@@ -115,6 +119,11 @@ module DEBUGGER__
|
|
115
119
|
end
|
116
120
|
end
|
117
121
|
|
122
|
+
def matchable_location
|
123
|
+
# realpath can sometimes be nil so we can't use it here
|
124
|
+
"#{path}:#{location.lineno}"
|
125
|
+
end
|
126
|
+
|
118
127
|
def location_str
|
119
128
|
"#{pretty_path}:#{location.lineno}"
|
120
129
|
end
|
@@ -138,18 +147,6 @@ module DEBUGGER__
|
|
138
147
|
end
|
139
148
|
end
|
140
149
|
|
141
|
-
private
|
142
|
-
|
143
|
-
def get_singleton_class obj
|
144
|
-
obj.singleton_class # TODO: don't use it
|
145
|
-
rescue TypeError
|
146
|
-
nil
|
147
|
-
end
|
148
|
-
|
149
|
-
private def local_variable_get var
|
150
|
-
local_variables[var]
|
151
|
-
end
|
152
|
-
|
153
150
|
def parameters_info
|
154
151
|
vars = iseq.parameters_symbols
|
155
152
|
vars.map{|var|
|
@@ -161,7 +158,17 @@ module DEBUGGER__
|
|
161
158
|
}.compact
|
162
159
|
end
|
163
160
|
|
164
|
-
def
|
161
|
+
private def get_singleton_class obj
|
162
|
+
obj.singleton_class # TODO: don't use it
|
163
|
+
rescue TypeError
|
164
|
+
nil
|
165
|
+
end
|
166
|
+
|
167
|
+
private def local_variable_get var
|
168
|
+
local_variables[var]
|
169
|
+
end
|
170
|
+
|
171
|
+
private def klass_sig
|
165
172
|
if self.class == get_singleton_class(self.self)
|
166
173
|
"#{self.self}."
|
167
174
|
else
|
data/lib/debug/server.rb
CHANGED
@@ -49,6 +49,7 @@ module DEBUGGER__
|
|
49
49
|
accept do |server, already_connected: false|
|
50
50
|
DEBUGGER__.warn "Connected."
|
51
51
|
greeting_done = false
|
52
|
+
@need_pause_at_first = true
|
52
53
|
|
53
54
|
@accept_m.synchronize{
|
54
55
|
@sock = server
|
@@ -68,7 +69,7 @@ module DEBUGGER__
|
|
68
69
|
} unless already_connected
|
69
70
|
|
70
71
|
setup_interrupt do
|
71
|
-
pause
|
72
|
+
pause if !already_connected && @need_pause_at_first
|
72
73
|
process
|
73
74
|
end
|
74
75
|
|
@@ -106,6 +107,24 @@ module DEBUGGER__
|
|
106
107
|
end
|
107
108
|
end
|
108
109
|
|
110
|
+
def parse_option params
|
111
|
+
case params.strip
|
112
|
+
when /width:\s+(\d+)/
|
113
|
+
@width = $1.to_i
|
114
|
+
parse_option $~.post_match
|
115
|
+
when /cookie:\s+(\S+)/
|
116
|
+
check_cookie $1 if $1 != '-'
|
117
|
+
parse_option $~.post_match
|
118
|
+
when /nonstop: (true|false)/
|
119
|
+
@need_pause_at_first = false if $1 == 'true'
|
120
|
+
parse_option $~.post_match
|
121
|
+
when /(.+):(.+)/
|
122
|
+
raise GreetingError, "Unkown option: #{params}"
|
123
|
+
else
|
124
|
+
# OK
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
109
128
|
def greeting
|
110
129
|
case g = @sock.gets
|
111
130
|
when /^info cookie:\s+(.*)$/
|
@@ -116,16 +135,18 @@ module DEBUGGER__
|
|
116
135
|
@sock.close
|
117
136
|
raise GreetingError, "HEAD request"
|
118
137
|
|
119
|
-
when /^version:\s+(
|
120
|
-
v,
|
138
|
+
when /^version:\s+(\S+)\s+(.+)$/
|
139
|
+
v, params = $1, $2
|
140
|
+
|
121
141
|
# TODO: protocol version
|
122
142
|
if v != VERSION
|
123
143
|
raise GreetingError, "Incompatible version (server:#{VERSION} and client:#{$1})"
|
124
144
|
end
|
145
|
+
parse_option(params)
|
125
146
|
|
126
|
-
|
127
|
-
|
128
|
-
|
147
|
+
puts "DEBUGGER (client): Connected. PID:#{Process.pid}, $0:#{$0}"
|
148
|
+
puts "DEBUGGER (client): Type `Ctrl-C` to enter the debug console." unless @need_pause_at_first
|
149
|
+
puts
|
129
150
|
|
130
151
|
when /^Content-Length: (\d+)/
|
131
152
|
require_relative 'server_dap'
|
@@ -133,12 +154,15 @@ module DEBUGGER__
|
|
133
154
|
raise unless @sock.read(2) == "\r\n"
|
134
155
|
self.extend(UI_DAP)
|
135
156
|
@repl = false
|
157
|
+
@need_pause_at_first = false
|
136
158
|
dap_setup @sock.read($1.to_i)
|
159
|
+
|
137
160
|
when /^GET \/.* HTTP\/1.1/
|
138
161
|
require_relative 'server_cdp'
|
139
162
|
|
140
163
|
self.extend(UI_CDP)
|
141
164
|
@repl = false
|
165
|
+
@need_pause_at_first = false
|
142
166
|
CONFIG.set_config no_color: true
|
143
167
|
|
144
168
|
@ws_server = UI_CDP::WebSocketServer.new(@sock)
|
@@ -164,6 +188,7 @@ module DEBUGGER__
|
|
164
188
|
}
|
165
189
|
end
|
166
190
|
|
191
|
+
return unless line
|
167
192
|
next if line == :can_not_read
|
168
193
|
|
169
194
|
case line
|
@@ -187,7 +212,7 @@ module DEBUGGER__
|
|
187
212
|
raise "pid:#{Process.pid} but get #{line}"
|
188
213
|
end
|
189
214
|
else
|
190
|
-
STDERR.puts "unsupported: #{line}"
|
215
|
+
STDERR.puts "unsupported: #{line.inspect}"
|
191
216
|
exit!
|
192
217
|
end
|
193
218
|
end
|
@@ -309,7 +334,9 @@ module DEBUGGER__
|
|
309
334
|
end
|
310
335
|
|
311
336
|
def readline prompt
|
312
|
-
input = (sock do |s|
|
337
|
+
input = (sock(skip: CONFIG[:skip_bp]) do |s|
|
338
|
+
next unless s
|
339
|
+
|
313
340
|
if @repl
|
314
341
|
raise "not in subsession, but received: #{line.inspect}" unless @session.in_subsession?
|
315
342
|
line = "input #{Process.pid}"
|
@@ -353,8 +380,8 @@ module DEBUGGER__
|
|
353
380
|
|
354
381
|
class UI_TcpServer < UI_ServerBase
|
355
382
|
def initialize host: nil, port: nil
|
356
|
-
@
|
357
|
-
@host = host || CONFIG[:host]
|
383
|
+
@local_addr = nil
|
384
|
+
@host = host || CONFIG[:host]
|
358
385
|
@port_save_file = nil
|
359
386
|
@port = begin
|
360
387
|
port_str = (port && port.to_s) || CONFIG[:port] || raise("Specify listening port by RUBY_DEBUG_PORT environment variable.")
|
@@ -375,12 +402,12 @@ module DEBUGGER__
|
|
375
402
|
def chrome_setup
|
376
403
|
require_relative 'server_cdp'
|
377
404
|
|
378
|
-
unless @chrome_pid = UI_CDP.setup_chrome(@
|
405
|
+
unless @chrome_pid = UI_CDP.setup_chrome(@local_addr.inspect_sockaddr)
|
379
406
|
DEBUGGER__.warn <<~EOS
|
380
407
|
With Chrome browser, type the following URL in the address-bar:
|
381
408
|
|
382
|
-
devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=#{@
|
383
|
-
|
409
|
+
devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=#{@local_addr.inspect_sockaddr}/#{SecureRandom.uuid}
|
410
|
+
|
384
411
|
EOS
|
385
412
|
end
|
386
413
|
end
|
@@ -391,9 +418,9 @@ module DEBUGGER__
|
|
391
418
|
|
392
419
|
begin
|
393
420
|
Socket.tcp_server_sockets @host, @port do |socks|
|
394
|
-
@
|
421
|
+
@local_addr = socks.first.local_address # Change this part if `socks` are multiple.
|
395
422
|
rdbg = File.expand_path('../../exe/rdbg', __dir__)
|
396
|
-
DEBUGGER__.warn "Debugger can attach via TCP/IP (#{@
|
423
|
+
DEBUGGER__.warn "Debugger can attach via TCP/IP (#{@local_addr.inspect_sockaddr})"
|
397
424
|
|
398
425
|
if @port_save_file
|
399
426
|
File.write(@port_save_file, "#{socks[0].local_address.ip_port.to_s}\n")
|
@@ -403,7 +430,7 @@ module DEBUGGER__
|
|
403
430
|
DEBUGGER__.info <<~EOS
|
404
431
|
With rdbg, use the following command line:
|
405
432
|
#
|
406
|
-
# #{rdbg} --attach #{@
|
433
|
+
# #{rdbg} --attach #{@local_addr.ip_address} #{@local_addr.ip_port}
|
407
434
|
#
|
408
435
|
EOS
|
409
436
|
|
@@ -411,7 +438,7 @@ module DEBUGGER__
|
|
411
438
|
when 'chrome'
|
412
439
|
chrome_setup
|
413
440
|
when 'vscode'
|
414
|
-
vscode_setup @
|
441
|
+
vscode_setup @local_addr.inspect_sockaddr
|
415
442
|
end
|
416
443
|
|
417
444
|
Socket.accept_loop(socks) do |sock, client|
|
data/lib/debug/server_cdp.rb
CHANGED
@@ -346,7 +346,7 @@ module DEBUGGER__
|
|
346
346
|
send_event 'Runtime.executionContextCreated',
|
347
347
|
context: {
|
348
348
|
id: SecureRandom.hex(16),
|
349
|
-
origin: "http://#{@
|
349
|
+
origin: "http://#{@local_addr.inspect_sockaddr}",
|
350
350
|
name: ''
|
351
351
|
}
|
352
352
|
when 'Runtime.getIsolateId'
|
@@ -572,13 +572,13 @@ module DEBUGGER__
|
|
572
572
|
def process_protocol_request req
|
573
573
|
case req['method']
|
574
574
|
when 'Debugger.stepOver', 'Debugger.stepInto', 'Debugger.stepOut', 'Debugger.resume', 'Debugger.enable'
|
575
|
-
|
575
|
+
request_tc [:cdp, :backtrace, req]
|
576
576
|
when 'Debugger.evaluateOnCallFrame'
|
577
577
|
frame_id = req.dig('params', 'callFrameId')
|
578
578
|
group = req.dig('params', 'objectGroup')
|
579
579
|
if fid = @frame_map[frame_id]
|
580
580
|
expr = req.dig('params', 'expression')
|
581
|
-
|
581
|
+
request_tc [:cdp, :evaluate, req, fid, expr, group]
|
582
582
|
else
|
583
583
|
fail_response req,
|
584
584
|
code: INVALID_PARAMS,
|
@@ -591,9 +591,9 @@ module DEBUGGER__
|
|
591
591
|
when 'local'
|
592
592
|
frame_id = ref[1]
|
593
593
|
fid = @frame_map[frame_id]
|
594
|
-
|
594
|
+
request_tc [:cdp, :scope, req, fid]
|
595
595
|
when 'properties'
|
596
|
-
|
596
|
+
request_tc [:cdp, :properties, req, oid]
|
597
597
|
when 'script', 'global'
|
598
598
|
# TODO: Support script and global types
|
599
599
|
@ui.respond req, result: []
|