class DEBUGGER__::Client - debug: Ruby Standard Library Documentation

# class DEBUGGER__::Client

### Public Class Methods

cleanup_unix_domain_sockets() click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 84
    def cleanup_unix_domain_sockets
      Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
        if File.socket?(file) && (/-(\d+)-\d+$/ =~ file || /-(\d+)$/ =~ file)
          begin
            Process.kill(0, $1.to_i)
          rescue Errno::EPERM
          rescue Errno::ESRCH
            File.unlink(file)
          end
        end
      end
    end

list_connections(verbose: false) click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 97
    def list_connections verbose: false
      socks = Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*').find_all do |path|
        File.socket?(path)
      end

      if verbose
        socks = socks.map{|sock_path|
          Socket.unix(sock_path){|sock|
            sock.puts "info cookie: #{CONFIG[:cookie] || '-'}"
            pid = sock.gets.chomp
            _dbg = sock.gets.chomp
            _unm = sock.gets.chomp
            [sock_path, pid]
          }
        }
      end

      socks
    end

new(argv) click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 118
    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] || '-'} " +
           "nonstop: #{CONFIG[:nonstop] ? 'true' : 'false'}"
    end

setup_autoload() click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 56
          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.10.0/lib/debug/client.rb, line 17
    def util name
      case name
      when 'gen-sockpath'
        puts DEBUGGER__.create_unix_domain_socket_name
      when 'gen-portpath'
        port_path = File.join(DEBUGGER__.unix_domain_socket_dir, 'tcp_port')
        File.unlink port_path if File.exist?(port_path)
        puts port_path
      when 'list-socks'
        cleanup_unix_domain_sockets
        puts list_connections
      when 'list-socks-verbose'
        cleanup_unix_domain_sockets
        puts list_connections verbose: true
      when 'setup-autoload'
        setup_autoload
      else
        abort "Unknown utility: #{name}"
      end
    end

working_shell_type() click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 38
    def working_shell_type
      shell = `ps -p #{Process.ppid} -o 'args='`
      case shell
      when /bash/
        :bash
      when /fish/
        :fish
      when /csh/
        :csh
      when /zsh/
        :zsh
      when /dash/
        :dash
      else
        :unknown
      end
    end

### Public Instance Methods

connect() click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 196
    def connect
      pre_commands = (CONFIG[:commands] || '').split(';;')

      trap(:SIGINT){
        send "pause"
      }

      begin
        trap(:SIGWINCH){
          @width = IO.console_size[1]
        }
      rescue ArgumentError
        @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
            if pre_commands.empty?
              line = readline
            else
              line = pre_commands.shift
              puts "(rdbg:remote:command) #{line}"
            end
          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} #{$stdin.gets || ''}"

        when /^quit/
          raise 'quit'

        else
          puts "(unknown) #{line.inspect}"
        end
      end
    rescue => e
      STDERR.puts "disconnected (#{e})"
      exit
    ensure
      deactivate
    end

connect_tcp(host, port) click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 187
    def connect_tcp host, port
      @s = Socket.tcp(host, port)
    end

connect_unix(name = nil) click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 159
    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
          files = Client.list_connections verbose: true
          $stderr.puts "Please select a debug session:"
          files.each{|(f, desc)|
            $stderr.puts "  #{File.basename(f)} (#{desc})"
          }
          exit
        end
      end
    end

deactivate() click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 147
    def deactivate
      @console.deactivate if @console
    end

readline() click to toggle source

    # File debug-1.10.0/lib/debug/client.rb, line 151
    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.10.0/lib/debug/client.rb, line 191
    def send msg
      p send: msg if $VERBOSE
      @s.puts msg
    end