debug 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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 (default: WARN)", :loglevel],
15
- show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint (default: 10 lines)", :int],
16
- show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint (default: 2 frames)", :int],
17
- use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool],
18
- no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize (default: false)", :bool],
19
- no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT (default: false)", :bool],
20
- no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library (default: false)", :bool],
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 (default: [])", :path],
24
- skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines (default: false)", :bool],
25
- keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it (default: false)", :bool],
26
- postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug (default: false)", :bool],
27
- fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child) (default: both)", :forkmode],
28
- sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal (default: disabled)"],
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 (default: ~/.rdbg_history)"],
37
- save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines (default: 10,000)"],
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 (localhost if not given)"],
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 (default: false)", :bool],
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
- update self.class.parse_argv(argv)
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 |_, new|
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
- else
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'] || 'ruby-debug'
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] || File.expand_path("~/.rdbg_history")
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] || 10_000
211
+ max = CONFIG[:save_history]
206
212
 
207
213
  if !added_records.empty? && !path.empty?
208
214
  orig_records = read_history_file
@@ -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 = self.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, _args = block_identifier
56
+ level, block_loc = block_identifier
53
57
  "block in #{block_loc}#{level}"
54
58
  when :method
55
- ci, _args = method_identifier
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, args]
90
+ [level || "", block_loc]
89
91
  end
90
92
 
91
93
  def method_identifier
92
94
  return unless frame_type == :method
93
- args = parameters_info
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 ||= self.binding&.eval('__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 klass_sig
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 unless already_connected
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+(.+)\s+width: (\d+) cookie:\s+(.*)$/
120
- v, w, c = $1, $2, $3
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
- check_cookie c
127
-
128
- @width = w.to_i
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
- @addr = nil
357
- @host = host || CONFIG[:host] || '127.0.0.1'
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(@addr)
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=#{@addr}/#{SecureRandom.uuid}
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
- @addr = socks[0].local_address.inspect_sockaddr # Change this part if `socks` are multiple.
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 (#{@addr})"
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 #{@addr.split(':').join(' ')}
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 @addr
441
+ vscode_setup @local_addr.inspect_sockaddr
415
442
  end
416
443
 
417
444
  Socket.accept_loop(socks) do |sock, client|
@@ -346,7 +346,7 @@ module DEBUGGER__
346
346
  send_event 'Runtime.executionContextCreated',
347
347
  context: {
348
348
  id: SecureRandom.hex(16),
349
- origin: "http://#{@addr}",
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
- @tc << [:cdp, :backtrace, req]
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
- @tc << [:cdp, :evaluate, req, fid, expr, group]
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
- @tc << [:cdp, :scope, req, fid]
594
+ request_tc [:cdp, :scope, req, fid]
595
595
  when 'properties'
596
- @tc << [:cdp, :properties, req, oid]
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: []