【问题标题】:The rubymine in OSX can't attach to a rdebug-ide started sessionOSX 中的 ruby​​mine 无法附加到 rdebug-ide 启动的会话
【发布时间】:2012-12-17 06:53:17
【问题描述】:

表面问题是:rubymine可以运行ruby程序,但不能调试,也不能远程调试,我得到了:

>> DIALOG: Connecting to debugger using 10 seconds

大约 10 秒后

>> DIALOG: Cannot connect to the debugged process at port 57000 [a random port]
>>>         Dumping and destroying...
>>>         Error Output: 
>>>         Fast Debugger(ruby-debug-ide 0.4.17.beta14, ruby-debug-base19 0.11.30.pre10) listens on 127.0.0.1:57000
>> Please try increase timeout settings...(a long bullshit)

我尝试通过阅读ruby-debug-ide和ruby-debug-base19代码找到根本原因,发现:

  1. ruby-debug-ide 已启动 DebugThread(@control_thread),它将在 127.0.0.1 上启动 TCPServer 绑定并侦听端口 57000。
  2. ruby-debug-ide 正在等待客户端连接到 tcp 服务器并向他发送“启动”命令到run_prog_script
  3. 我可以telnet 127.0.0.1 57000,然后Debug Thread说:Connected from 127.0.0.1 ... 如果我在 telnet 中输入一个单词 'start\n',rdebug-ide 将启动我的真实程序。
  4. Rubymine 尚未连接到它并发送“启动”命令。 (因为我在idea.log中没有找到任何输出)

我深入研究了idea.log:

Fast Debugger (ruby-debug-ide 0.4.17.beta14, ruby-debug-base 0.11.30.pre10) listens on   127.0.0.1:59598
at org.rubyforge.debugcommons.RubyDebuggerProxy.a(RubyDebuggerProxy.java:647)
at org.rubyforge.debugcommons.RubyDebuggerProxy.d(RubyDebuggerProxy.java:619)
at org.rubyforge.debugcommons.RubyDebuggerProxy.getCommandSocket(RubyDebuggerProxy.java:381)
at org.rubyforge.debugcommons.RubyDebuggerProxy.b(RubyDebuggerProxy.java:151)
at org.rubyforge.debugcommons.RubyDebuggerProxy.attach(RubyDebuggerProxy.java:112)
at org.jetbrains.plugins.ruby.ruby.debugger.impl.RubyDebugProcess.attachToProxy(RubyDebugProcess.java:190)

然后我阅读了debug-commons代码(不如rubymine准确,我参考https://github.com/ruby-debug/debug-commons-java/blob/master/src/org/rubyforge/debugcommons/RubyDebuggerProxy.java

private Socket attach() throws RubyDebuggerException {
  int port = debugTarget.getPort();
  String host = debugTarget.getHost();
  Socket socket = null;
  for (int tryCount = (timeout*2), i = 0; i < tryCount && socket == null; i++) {
    try {
          socket = new Socket(host, port);
          ...
    }
  }
}

似乎 ruby​​mine 无法使用 debug-commons lib 在 localhost 打开套接字连接,我无法挖掘更多内容:(

顺便说一句,即使我们通过以下命令在 shell 中启动 ruby​​ 调试会话:

rdebug-ide --port 51202 -- path/to/my/script

rubymine 也无法连接到套接字。

*不要告诉我我应该使用另一个 ruby​​-debug-xxx gem 或删除其他一些 gem,例如 ruby​​-debug,我已经尝试过这些解决方案。 *

我尝试过以下组:

组 1:

  • 红宝石4.0.3
  • ruby-debug-base19-0.11.29
  • ruby-debug-ide-0.4.16

组2:

  • 红宝石 4.5.x
  • ruby-debug-base19-0.11.30.pre10
  • ruby-debug-ide-0.4.17.beta14

我的笔记本电脑是装有 OSX Lion 的 mac air

【问题讨论】:

  • 防火墙阻止连接?在 RubyMine 中配置了代理?试试看tcpdump/wireshark会发生什么。
  • 您在系统偏好设置中指定了计算机名称吗?分享?
  • 我有一个计算机名为“air”,但无法删除。

标签: ruby macos debugging rubymine


【解决方案1】:

我有同样的问题。我尝试了所有建议(删除 ruby​​-debug、行缓存等),但都没有奏效。就我而言,我的 macbook 的主机名设置为 localhost。我更改了我的主机名sudo scutil --set HostName newHostName,现在它可以完美运行了。

【讨论】:

    【解决方案2】:

    我应该使用远程调试器而不是本地调试器。

    首先,比较本地调试错误:

    Error:
    
      Cannot connect to the debugged process at port 57000 [a random port]
    
      Dumping and destroying...
    
      Error Output: 
      Fast Debugger(ruby-debug-ide 0.4.17.beta14, ruby-debug-base19 0.11.30.pre10) listens on 127.0.0.1:57000
    
      Please try increase timeout settings...(a long bullshit)
    

    使用 debug-commons-java'code:

    private void failWithInfo(ConnectException e) throws RubyDebuggerException {
        String info = debugTarget.isRemote()
                ? "[Remote Process at " + debugTarget.getHost() + ':' + debugTarget.getPort() + "]"
                : Util.dumpAndDestroyProcess(debugTarget);
        throw new RubyDebuggerException("Cannot connect to the debugged process at port "
                + debugTarget.getPort() + " in " + timeout + "s:\n\n" + info, e);
    }
    

    我在上面的错误输出中看不到任何 debugTarget.getHost(),但如果我们远程调试它会告诉我主机。

    于是我写了一个最简单的ruby脚本(test.rb):

    i = 10
    begin
      puts "echo ok #{i}"
      i += 1
      sleep 1
    end until i > 600
    

    然后在Ruby mine默认配置下启动远程调试会话:

    • 远程主机:本地主机
    • 远程端口:1234
    • 远程根文件夹:path/to/test
    • 本地端口:26201
    • 本地根文件夹:path/to/test

    我发现 ruby​​mine 显示异常为:

    Error:
    
      Cannot connect to debugged process at port 54321 in 10s:
    
      [Remote Process at **localhost**:54321]
    

    然后我将远程主机改为“127.0.0.1”,完成!

    所以我猜 Rubymine 会尝试使用“localhost”作为主机名连接到调试目标,但它失败了!

    我试图找到 debugTarget 的主机被初始化的位置,我在 debug commons RubyDebuggerFactory 中获得了这些代码:

    private static RubyDebuggerProxy startDebugger(final Descriptor desc, final List<String> args, final int timeout)
            throws IOException, RubyDebuggerException {
    
       ...
        // 127.0.0.1 seemingly works with all systems and with IPv6 as well.
        // "localhost" and InetAddress.getLocalHost() have problems on some systems.
        // cf. http://www.netbeans.org/issues/show_bug.cgi?id=143273 for one case
        RubyDebugTarget target = new RubyDebugTarget(proxy, "127.0.0.1", desc.getPort(),
                pb.start(), desc.getDebuggeePath(), desc.getBaseDirectory());
        proxy.setDebugTarget(target);
        RubyDebuggerProxy.PROXIES.add(proxy);
        return proxy;
    }
    

    反编译 ruby​​mine.jar 为 org.rubyforge.debugcommons.RubyDebuggerFactory,虽然杂乱无章,但我们可以找到:

        RubyDebugTarget rubydebugtarget = new RubyDebugTarget(rubydebuggerproxy, "127.0.0.1", descriptor.getPort(), processbuilder.start(), descriptor.getDebuggeePath(), descriptor.getBaseDirectory());
    

    我认为 ruby​​mine 连接到 127.0.0.1 但没有足够的权限,所以我尝试通过以下命令启动 ruby​​ mine:

    sudo /Applications/Rubymine.app/Contents/MacOSX/rubymine

    但是还是失败了,所以是rubymine的bug,如果你和我一样有这么糟糕的体验,用远程调试器来避免吧。

    感谢Dennis Ushakov提醒计算机名称

    【讨论】:

    • 我的结论是:当我为本地脚本启动调试器时,Rubymine 将 debugTarget 设置为“localhost”,这会覆盖调试公共硬代码中的“127.0.0.1”。
    猜你喜欢
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2017-05-29
    • 2023-03-10
    相关资源
    最近更新 更多