检查为什么Ruby脚本挂起(Check why ruby script hangs)

2019-07-03 20:33发布

有时候,我的规格可以只是闲逛,我要杀死相应的红宝石过程。 这是相当常见的,当我运行与水豚和WebKit驱动书面整合规范。

是否有可能来检查给Ruby的过程,看看它挂? 哪一种方法,操作,文件,行号等。

Answer 1:

TL;博士

使用gdb (如Linux)的:

  • echo 'call (void)rb_backtrace()' | gdb -p $(pgrep -f ruby)

或使用lldb (例如OS X):

  • echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -f ruby)

您可以通过使用调试库调试Ruby脚本。

如果脚本从壳执行时,这可以通过改变第一线(可以实现认领脚本成的):

#!/usr/bin/env ruby -rdebug

或运行它为:

ruby -rdebug my_script.rb

一旦调试器加载,你可以建立一些断点,或只是通过键入运行应用程序c继续执行。

然后调试器自动断开上的任何异常(例如Ctrl + C)或断点(例如,其由行debugger )。

然后,每当显示调试器控制台,您可以选择:

  • c为继续(到下一个异常,断点或符合: debugger ),
  • n为下一行,
  • w / where要显示的帧/调用堆栈
  • l ,显示当前的代码,
  • cat显示捕获点。
  • h更多的帮助。

参见: 红宝石调试调试 , 红宝石调试宝石快捷键 。

这种方法的缺点是,有没有神奇的按钮,以提高对需求的调试器,比养在脚本中的异常,以及它会显示不同的代码块,而不是挂一个其他。

这里有一些其他的想法:

  • 添加debugger语句转换成你的代码,提高调试器,一步一步来。
  • 使用撬调试器,而不是(见: GitHub上 )。

    通过安装: gem install pry ,如运行: pry或者添加为require 'pry'

  • 尝试lldb调试器(它旨在取代gdb ),它可以附加到当前正在运行的进程。

    例如(更换PID与进程id):

     $ lldb -p PID (lldb) bt all * thread #1: tid = 0x11d68a, 0x00007fff86c71716 libsystem_kernel.dylib`__psynch_cvwait + 10 * frame #0: 0x00007fff86c71716 libsystem_kernel.dylib`__psynch_cvwait + 10 frame #1: 0x00007fff838a9c3b libsystem_pthread.dylib`_pthread_cond_wait + 727 frame #2: 0x0000000100241aad libruby.2.0.0.dylib`native_cond_wait + 29 

    显示的实时运行Ruby脚本回溯(在其TTY)又如:

     echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -f ruby) 
  • 或者使用gdb (你可以扩展它: gdb.rb它可以告诉你红宝石的对象)。

    1. 通过安装: sudo apt-get install gdb python-dev ncurses-dev && gem install gdb.rb
    2. 在Unix / OS X按Ctrl + T就挂过程检查PID,什么是做(或通过检查ps wuax | grep ruby )。
    3. 附加到经由该过程: gdb -p PID

    参见: 用gdb检查挂起的Ruby进程 , GDB包装为Ruby和检查现场Ruby进程 。

  • 其他库/工具,它可以帮助包括: 调试器 , 碰撞手表 , memprof , 机架perftools_profiler 。

如果没有什么帮助,你可以简单地尝试: strace (Linux)的/ dtruss (OS X)的语法如下:

sudo strace -fp <PID>
sudo dtruss -fp <PID>

ltrace它可以跟踪,而不是库调用strace的系统调用。

如果你认为这是一个网络问题,请使用tcpdump

也可以看看:

  • 如何调试Ruby脚本?
  • 如何配置红宝石就按Ctrl-C(SIGINT)进入调试?
  • 如何用键盘打入运行Rails应用程序的红宝石调试?
  • 有没有办法使用一个按键来调用撬红宝石宝石的方法吗?
  • 调试滞留红宝石过程-你杀之前做什么-9
  • 调试工具运行Ruby的过程和调试的Ruby工具
  • 调试Rails应用程序
  • 正确的方式来处理在Unix冻结的进程
  • 调试中的Unix的Ruby应用程序由塞尔吉·博伊科
  • 调试使用Ruby调试在JumpstartLab
  • 红宝石调试在30秒(我们不需要任何讨厌的GUI!)
  • 如何调试卡红宝石过程


Answer 2:

我有这个问题,以及和它追溯到一个ShareThis特定页面上的JavaScript小部件。 您可能会或可能不会用这个,但真正的问题也许是它的悬挂,因为页面上的东西造成的是无法完成外部请求。 水豚,WebKit的会知道原始请求,但如果这个代码本身发出请求,水豚,WebKit的永远不会知道这件事,如果这最后的请求挂起,说等待响应,所以将水豚,WebKit的...

对你来说,使用WebKit的调试运行测试,看看时发出的最后请求。 对于我来说,我看到以下内容:

    1 requests remaining 
    Page finished with true 
    Received 200 from "http://w.sharethis.com/share4x/js/st.60709d5fdf0c137e879e64f41b8a6606.js" 
    0 requests remaining 
    Started request to "http://w.sharethis.com/share4x/css/share.470030190b6a6bdc89365fcc74d3bf55.css" 
    Received 200 from "http://w.sharethis.com/share4x/css/share.470030190b6a6bdc89365fcc74d3bf55.css" 
    0 requests remaining 

这避让我搜索我的ShareThis的代码库。 我把一个if(Rails.env.test?)块周围的代码,瞧,我在生意。 它是一个蹩脚的解决方法,必须把对测试环境条件语句到你的代码...但它让我从这个愚蠢的问题...移动

希望这可以帮助。



文章来源: Check why ruby script hangs