Class: DEBUGGER__::Config
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/debug/config.rb |
Class Method Summary
Instance Attribute Summary
- #skip? ⇒ Boolean readonly
Instance Method Summary
- #[](key)
- #[]=(key, val)
- #append_config(key, val)
- #inspect
- #set_config(**kw)
- #skip_all
- #update(conf)
- #config private
- #disable_sigdump(old_sig) private
- #enable_sigdump(sig) private
- #if_updated(old_conf, new_conf, key) {|old, new| ... } private
- #parse_config_value(name, valstr) private
-
#setup_sigdump(old_sig = nil, sig = )
private
emergency simple sigdump.
Constructor Details
.new(argv) ⇒ Config
# File 'lib/debug/config.rb', line 65
def initialize argv @skip_all = false if self.class.config raise 'Can not make multiple configurations in one process' end config = self.class.parse_argv(argv) # apply defaults CONFIG_SET.each do |k, config_detail| unless config.key?(k) default_value = config_detail[3] config[k] = parse_config_value(k, default_value) end end update config end
Class Method Details
.config
[ GitHub ]# File 'lib/debug/config.rb', line 61
def self.config @config end
.config_to_env_hash(config)
[ GitHub ]# File 'lib/debug/config.rb', line 387
def self.config_to_env_hash config CONFIG_MAP.each_with_object({}){|(key, evname), env| unless config[key].nil? case CONFIG_SET[key][2] when :path valstr = config[key].map{|e| e.kind_of?(Regexp) ? e.inspect : e}.join(':') when :path_map valstr = config[key].map{|e| e.join(':')}.join(',') else valstr = config[key].to_s end env[evname] = valstr end } end
.parse_argv(argv)
[ GitHub ]# File 'lib/debug/config.rb', line 251
def self.parse_argv argv config = { mode: :start, no_color: (nc = ENV['NO_COLOR']) && !nc.empty?, } CONFIG_MAP.each{|key, evname| if val = ENV[evname] config[key] = parse_config_value(key, val) end } return config if !argv || argv.empty? if argv.kind_of? String require 'shellwords' argv = Shellwords.split(argv) end require 'optparse' require_relative 'version' opt = OptionParser.new do |o| o. = "#{$0} [options] -- [debuggee options]" o.separator '' o.version = ::DEBUGGER__::VERSION o.separator 'Debug console mode:' o.on('-n', '--nonstop', 'Do not stop at the beginning of the script.') do config[:nonstop] = '1' end o.on('-e DEBUG_COMMAND', 'Execute debug command at the beginning of the script.') do |cmd| config[:commands] ||= '' config[:commands] += cmd + ';;' end o.on('-x FILE', '--init-script=FILE', 'Execute debug command in the FILE.') do |file| config[:init_script] = file end o.on('--no-rc', 'Ignore ~/.rdbgrc') do config[:no_rc] = true end o.on('--no-color', 'Disable colorize') do config[:no_color] = true end o.on('--no-sigint-hook', 'Disable to trap SIGINT') do config[:no_sigint_hook] = true end o.on('-c', '--command', 'Enable command mode.', 'The first argument should be a command name in $PATH.', 'Example: \'rdbg -c bundle exec rake test\'') do config[:command] = true end o.separator '' o.on('-O', '--open=[FRONTEND]', 'Start remote debugging with opening the network port.', 'If TCP/IP options are not given, a UNIX domain socket will be used.', 'If FRONTEND is given, prepare for the FRONTEND.', 'Now rdbg, vscode and chrome is supported.') do |f| config[:remote] = true config[:open_frontend] = f.downcase if f end o.on('--sock-path=SOCK_PATH', 'UNIX Domain socket path') do |path| config[:sock_path] = path end o.on('--port=PORT', 'Listening TCP/IP port') do |port| config[:port] = port end o.on('--host=HOST', 'Listening TCP/IP host') do |host| config[:host] = host end o.on('--cookie=COOKIE', 'Set a cookie for connection') do |c| config[: ] = c end rdbg = 'rdbg' o.separator '' o.separator ' Debug console mode runs Ruby program with the debug console.' o.separator '' o.separator " '#{rdbg} target.rb foo bar' starts like 'ruby target.rb foo bar'." o.separator " '#{rdbg} -- -r foo -e bar' starts like 'ruby -r foo -e bar'." o.separator " '#{rdbg} -c rake test' starts like 'rake test'." o.separator " '#{rdbg} -c -- rake test -t' starts like 'rake test -t'." o.separator " '#{rdbg} -c bundle exec rake test' starts like 'bundle exec rake test'." o.separator " '#{rdbg} -O target.rb foo bar' starts and accepts attaching with UNIX domain socket." o.separator " '#{rdbg} -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234." o.separator " '#{rdbg} -O --port 1234 -- -r foo -e bar' starts accepts attaching with TCP/IP localhost:1234." o.separator " '#{rdbg} target.rb -O chrome --port 1234' starts and accepts connecting from Chrome Devtools with localhost:1234." o.separator '' o.separator 'Attach mode:' o.on('-A', '--attach', 'Attach to debuggee process.') do config[:mode] = :attach end o.separator '' o.separator ' Attach mode attaches the remote debug console to the debuggee process.' o.separator '' o.separator " '#{rdbg} -A' tries to connect via UNIX domain socket." o.separator " #{' ' * rdbg.size} If there are multiple processes are waiting for the" o.separator " #{' ' * rdbg.size} debugger connection, list possible debuggee names." o.separator " '#{rdbg} -A path' tries to connect via UNIX domain socket with given path name." o.separator " '#{rdbg} -A port' tries to connect to localhost:port via TCP/IP." o.separator " '#{rdbg} -A host port' tries to connect to host:port via TCP/IP." o.separator '' o.separator 'Other options:' o.on("-h", "--help", "Print help") do puts o exit end o.on('--util=NAME', 'Utility mode (used by tools)') do |name| require_relative 'client' Client.util(name) exit end o.on('--stop-at-load', 'Stop immediately when the debugging feature is loaded.') do config[:stop_at_load] = true end o.separator '' o.separator 'NOTE' o.separator ' All messages communicated between a debugger and a debuggee are *NOT* encrypted.' o.separator ' Please use the remote debugging feature carefully.' end opt.parse!(argv) config end
.parse_config_value(name, valstr)
[ GitHub ]# File 'lib/debug/config.rb', line 210
def self.parse_config_value name, valstr return valstr unless valstr.kind_of? String case CONFIG_SET[name][2] when :bool case valstr when '1', 'true', 'TRUE', 'T' true else false end when :int valstr.to_i when :loglevel if DEBUGGER__::LOG_LEVELS[s = valstr.to_sym] s else raise "Unknown loglevel: #{valstr}" end when :forkmode case sym = valstr.to_sym when :parent, :child, :both, nil sym else raise "unknown fork mode: #{sym}" end when :path # array of String valstr.split(/:/).map{|e| if /\A\/(.+)\/\z/ =~ e Regexp.compile $1 else e end } when :path_map valstr.split(',').map{|e| e.split(':')} else valstr end end
Instance Attribute Details
#skip? ⇒ Boolean
(readonly)
[ GitHub ]
# File 'lib/debug/config.rb', line 101
def skip? @skip_all end
Instance Method Details
#[](key)
[ GitHub ]# File 'lib/debug/config.rb', line 89
def [](key) config[key] end
#[]=(key, val)
[ GitHub ]# File 'lib/debug/config.rb', line 93
def []=(key, val) set_config(key => val) end
#append_config(key, val)
[ GitHub ]# File 'lib/debug/config.rb', line 118
def append_config key, val conf = config.dup if CONFIG_SET[key] if CONFIG_SET[key][2] == :path conf[key] = [*conf[key], *parse_config_value(key, val)]; else raise "not an Array type: #{key}" end else raise "Unknown configuration: #{key}" end update conf end
#config (private)
[ GitHub ]# File 'lib/debug/config.rb', line 202
private def config self.class.config end
#disable_sigdump(old_sig) (private)
[ GitHub ]# File 'lib/debug/config.rb', line 184
private def disable_sigdump old_sig trap(old_sig, @sigdump_sig_prev) @sigdump_sig_prev = nil end
#enable_sigdump(sig) (private)
[ GitHub ]# File 'lib/debug/config.rb', line 168
private def enable_sigdump sig @sigdump_sig_prev = trap(sig) do str = [] str << "Simple sigdump on #{Process.pid}" Thread.list.each{|th| str << "Thread: #{th}" th.backtrace.each{|loc| str << " #{loc}" } str << '' } STDERR.puts str end end
#if_updated(old_conf, new_conf, key) {|old, new| ... } (private)
#inspect
[ GitHub ]# File 'lib/debug/config.rb', line 85
def inspect config.inspect end
#parse_config_value(name, valstr) (private)
[ GitHub ]# File 'lib/debug/config.rb', line 206
private def parse_config_value name, valstr self.class.parse_config_value name, valstr end
#set_config(**kw)
[ GitHub ]# File 'lib/debug/config.rb', line 105
def set_config(**kw) conf = config.dup kw.each{|k, v| if CONFIG_MAP[k] conf[k] = parse_config_value(k, v) # TODO: ractor support else raise "Unknown configuration: #{k}" end } update conf end
#setup_sigdump(old_sig = nil, sig = ) (private)
emergency simple sigdump. Use sigdump
gem for more rich features.
# File 'lib/debug/config.rb', line 191
private def setup_sigdump old_sig = nil, sig = CONFIG[:sigdump_sig] if !old_sig && sig enable_sigdump sig elsif old_sig && !sig disable_sigdump old_sig elsif old_sig && sig disable_sigdump old_sig enable_sigdump sig end end
#skip_all
[ GitHub ]# File 'lib/debug/config.rb', line 97
def skip_all @skip_all = true end
#update(conf)
[ GitHub ]# File 'lib/debug/config.rb', line 134
def update conf old_conf = self.class.instance_variable_get(:@config) || {} # TODO: Use Ractor.make_shareable(conf) self.class.instance_variable_set(:@config, conf.freeze) # Post process if_updated old_conf, conf, :keep_alloc_site do |old, new| if new require 'objspace' ObjectSpace.trace_object_allocations_start end if old && !new ObjectSpace.trace_object_allocations_stop end end if_updated old_conf, conf, :postmortem do |_, new_p| if defined?(SESSION) SESSION.postmortem = new_p end end if_updated old_conf, conf, :sigdump_sig do |old_sig, new_sig| setup_sigdump old_sig, new_sig end end