class DEBUGGER__::Client

Public Class Methods

cleanup_unix_domain_sockets() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 77
def cleanup_unix_domain_sockets
  Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
    if /(\d+)$/ =~ file
      begin
        Process.kill(0, $1.to_i)
      rescue Errno::EPERM
      rescue Errno::ESRCH
        File.unlink(file)
      end
    end
  end
end
list_connections() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 90
def list_connections
  Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
end
new(argv) click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 95
def initialize argv
  @multi_process = false
  @pid = nil
  @console = Console.new

  case argv.size
  when 0
    connect_unix
  when 1
    if /\A\d+\z/ =~ (arg = argv.shift.strip)
      connect_tcp nil, arg.to_i
    else
      connect_unix arg
    end
  when 2
    connect_tcp argv[0], argv[1]
  else
    raise CommandLineOptionError
  end

  @width = IO.console_size[1]
  @width = 80 if @width == 0

  send "version: #{VERSION} width: #{@width} cookie: #{CONFIG[:cookie]}"
end
setup_autoload() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 49
      def setup_autoload
        prelude_path = File.join(__dir__, 'prelude.rb')

        case shell = working_shell_type
        when :bash, :zsh
          puts <<~EOS
          # add the following lines in your ~/.#{shell}_profile

          if test -s #{prelude_path} ; then
            export RUBYOPT='-r #{prelude_path}'
          fi

          # Add `Kernel#bb` method which is alias of `Kernel#debugger`
          # export RUBY_DEBUG_BB=1
          EOS

        when :fish
          puts <<~EOS
          # add the following lines in your ~/.config/fish/config.fish
          set -x RUBYOPT "-r #{__dir__}/prelude" $RUBYOPT
          EOS

        else
          puts "# Sorry that your shell is not supported yet.",
               "# Please use the content in #{prelude_path} as a reference and modify your login script accordingly."
        end
      end
util(name) click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 17
def util name
  case name
  when 'gen-sockpath'
    puts DEBUGGER__.create_unix_domain_socket_name
  when 'list-socks'
    cleanup_unix_domain_sockets
    puts list_connections
  when 'setup-autoload'
    setup_autoload
  else
    abort "Unknown utility: #{name}"
  end
end
working_shell_type() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 31
def working_shell_type
  shell = `ps -p #{Process.ppid} -o 'args='`
  case shell
  when /bash/
    :bash
  when /fish/
    :fish
  when /csh/
    :csh
  when /zsh/
    :szh
  when /dash/
    :dash
  else
    :unknown
  end
end

Public Instance Methods

connect() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 169
def connect
  trap(:SIGINT){
    send "pause"
  }

  begin
    trap(:SIGWINCH){
      @width = IO.console_size[1]
    }
  rescue ArgumentError => e
    @width = 80
  end

  while line = @s.gets
    p recv: line if $VERBOSE
    case line

    when /^out (.*)/
      puts "#{$1}"

    when /^input (.+)/
      pid = $1
      @multi_process = true if @pid && @pid != pid
      @pid = pid
      prev_trap = trap(:SIGINT, 'DEFAULT')

      begin
        line = readline
      rescue Interrupt
        retry
      ensure
        trap(:SIGINT, prev_trap)
      end

      line = (line || 'quit').strip
      send "command #{pid} #{@width} #{line}"

    when /^ask (\d+) (.*)/
      pid = $1
      print $2
      send "answer #{pid} #{gets || ''}"

    when /^quit/
      raise 'quit'

    else
      puts "(unknown) #{line.inspect}"
    end
  end
rescue
  STDERR.puts "disconnected (#{$!})"
  exit
ensure
  deactivate
end
connect_tcp(host, port) click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 160
def connect_tcp host, port
  @s = Socket.tcp(host, port)
end
connect_unix(name = nil) click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 133
def connect_unix name = nil
  if name
    if File.exist? name
      @s = Socket.unix(name)
    else
      @s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_dir, name))
    end
  else
    Client.cleanup_unix_domain_sockets
    files = Client.list_connections

    case files.size
    when 0
      $stderr.puts "No debug session is available."
      exit
    when 1
      @s = Socket.unix(files.first)
    else
      $stderr.puts "Please select a debug session:"
      files.each{|f|
        $stderr.puts "  #{File.basename(f)}"
      }
      exit
    end
  end
end
deactivate() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 121
def deactivate
  @console.deactivate if @console
end
readline() click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 125
def readline
  if @multi_process
    @console.readline "(rdbg:remote\##{@pid}) "
  else
    @console.readline "(rdbg:remote) "
  end
end
send(msg) click to toggle source
# File debug-1.4.0/lib/debug/client.rb, line 164
def send msg
  p send: msg if $VERBOSE
  @s.puts msg
end