检查 ruby​​ 脚本挂起的原因 [英] Check why ruby script hangs

查看:20
本文介绍了检查 ruby​​ 脚本挂起的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时我的规范可能会挂起,我不得不终止相应的 ruby​​ 进程.当我运行用 capybara 和 webkit 驱动程序编写的集成规范时,这是很常见的.

Sometimes my specs can just hang and I have to kill the corresponding ruby process. It's quite common when I run integration specs written with capybara and webkit driver.

是否可以检查给定的 ruby​​ 进程并查看它挂在哪里?哪个方法、操作、文件、行号等

Is it possible to inspect given ruby's process and see where it hangs? Which method, operation, file, line number etc.

推荐答案

tl;dr

使用 gdb(例如 Linux):

tl;dr

Use gdb (e.g. Linux):

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

或使用 lldb(例如 OS X):

or use lldb (e.g. OS X):

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

您可以使用调试库来调试 Ruby 脚本.

You can debug Ruby script by using debug library.

如果脚本是从 shell 执行的,这可以通过改变第一行来实现 (shebang) 的脚本变成:

If the script is executed from shell, this can be achieved by changing first line (shebang) of the script into:

#!/usr/bin/env ruby -rdebug

或将其运行为:

ruby -rdebug my_script.rb

加载调试器后,您可以设置一些断点,也可以通过键入 c 来运行应用程序以继续执行.

Once the debugger is loaded, you can either set-up some breakpoints or just run the app by typing c to continue the execution.

然后调试器会在任何异常(例如 Ctrl+C)或断点(例如包含 debugger 的行)上自动中断.

Then the debugger automatically breaks on any Exceptions (such as Ctrl+C) or breakpoints (e.g. the lines which consist debugger).

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

Then every time when debugger console is shown, you can choose between:

  • c 用于继续(到下一个异常、断点或行:debugger),
  • n 表示下一行,
  • w/where 显示帧/调用堆栈,
  • l 显示当前代码,
  • cat 显示捕捉点.
  • h 获得更多帮助.
  • c for Continue (to the next Exception, breakpoint or line with: debugger),
  • n for Next line,
  • w/where to Display frame/call stack,
  • l to Show the current code,
  • cat to show catchpoints.
  • h for more Help.

另见:使用 ruby​​-debug 调试ruby-debug gem 的快捷键.

这种方法的缺点是没有神奇的按钮来按需启动调试器,除了在脚本中引发异常之外,它将显示不同的代码块而不是挂起一个.

The downside of this method is that there is no magic button to raise the debugger on demand, other than raising the Exception within the script as well which will show different block of code rather than hung one.

这里有一些其他的想法:

Here are few other ideas:

  • debugger 语句添加到您的代码中,启动调试器并逐步执行.
  • 改用 Pry 调试器(请参阅:GitHub).

  • Add debugger statement into your code, raise the debugger and go step by step.
  • Use Pry debugger instead (see: GitHub).

通过:gem install pry 安装,运行方式为:pry 或添加为 require 'pry'.

Install via: gem install pry, run as: pry or add as require 'pry'.

尝试 lldb 调试器(旨在替换 gdb) 可以附加到当前运行的进程.

Try lldb debugger (which aiming to replace gdb) which can attach to the currently running process.

示例(将 PID 替换为您的进程 ID):

Example (replace PID with your process 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 上)的回溯的另一个示例:

Another example showing backtrace of live running ruby script (on its tty):

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

  • 或者使用 gdb(您可以通过以下方式扩展它:gdb.rb 可以显示 ruby​​ 对象).

  • Alternatively use gdb (you can extend it by: gdb.rb which can show you ruby objects).

    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.
    1. Install via: sudo apt-get install gdb python-dev ncurses-dev && gem install gdb.rb
    2. On Unix/OS X press Ctrl+T on hanging process to check the PID and what's doing (or check via ps wuax | grep ruby).
    3. Attach to the process via: gdb -p PID.

    另见:使用 gdb 检查挂起的 ruby​​ 进程GDB 包装器对于 Ruby检查实时 Ruby 进程.

    如果没有任何帮助,您可以简单地尝试:strace (Linux)/dtruss (OS X) 使用以下语法:

    If nothing helps, you can simply try: strace (Linux) /dtruss (OS X) with the following syntax:

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

    或者 ltrace 可以跟踪库调用而不是strace 系统调用.

    如果您认为这是网络问题,请使用 tcpdump.

    If you think it's a network issue, use tcpdump.

    另见:

    • How do I debug Ruby scripts?
    • How do I configure ruby to enter the debugger on Ctrl-C (SIGINT)?
    • How do I use the keyboard to break into ruby-debug running a rails app?
    • Is there a way to use a keystroke to invoke the pry ruby gem?
    • Debugging Stuck Ruby Processes – What to do Before You Kill -9
    • Tools for Debugging Running Ruby Processes and Debugging Ruby Tools
    • Debugging Rails Applications
    • The right way to deal with frozen processes on Unix
    • Debugging Ruby-applications in Unix by Sergii Boiko
    • Debugging using Ruby Debugger at JumpstartLab
    • ruby-debug in 30 seconds (we don't need no stinkin' GUI!)
    • How to debug stuck Ruby processes

    这篇关于检查 ruby​​ 脚本挂起的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆