有时我的规格可能会挂起,我必须杀死相应的ruby进程。当我运行用capybara和webkit驱动程序编写的集成规范时,这很常见。
是否有可能检查给定的红宝石过程并查看它挂在哪里?哪种方法,操作,文件,行号等。
答案 0 :(得分:7)
使用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脚本。
如果脚本是从shell执行的,可以通过将脚本的第一行(shebang)更改为:
来实现。#!/usr/bin/env ruby -rdebug
或将其作为:
运行ruby -rdebug my_script.rb
加载调试器后,您可以设置一些断点,也可以通过键入c
来运行应用程序来继续执行。
然后调试器自动中断任何异常(例如 Ctrl + C )或断点(例如由debugger
组成的行)。
然后,每次显示调试器控制台时,您都可以选择:
c
表示继续(到下一个例外,断点或行:debugger
),n
代表下一行,w
/ where
显示框架/调用堆栈,l
显示当前代码,cat
显示抓点。h
获取更多帮助。另请参阅:Debugging with ruby-debug,Key shortcuts for ruby-debug gem。
这种方法的缺点是没有魔术按钮来按需提升调试器,除了在脚本中引发异常,这将显示不同的代码块而不是挂起代码。
以下是其他一些想法:
debugger
语句,引发调试器并逐步执行。通过以下方式安装: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
,它可以显示红宝石对象)。
sudo apt-get install gdb python-dev ncurses-dev && gem install gdb.rb
ps wuax | grep ruby
检查)。gdb -p PID
。另请参阅:using gdb to inspect a hung ruby process,GDB wrapper for Ruby和Inspecting a live Ruby process。
如果没有任何帮助,您可以使用以下语法尝试:strace
(Linux)/ dtruss
(OS X):
sudo strace -fp <PID>
sudo dtruss -fp <PID>
或ltrace
可以跟踪库调用,而不是strace
系统调用。
如果您认为这是网络问题,请使用tcpdump
。
另见:
答案 1 :(得分:1)
我也有这个问题,并将其追溯到特定页面上的ShareThis javascript小部件。你可能会或可能不会使用它,但真正的问题可能是它的悬挂,因为页面上的某些内容导致永远不会完成的外部请求。 Capybara-webkit会知道原始请求,但是如果这个代码本身发出请求,capybara-webkit永远不会知道它,如果最后一个请求挂起,说等待响应,那么capybara-webkit ...... < / p>
对于您来说,使用webkit-debug运行测试并查看最后一个请求。对我来说,我看到了以下内容:
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?)块,瞧,我在做生意。它是一个糟糕的解决方法,必须将测试环境的条件放入你的代码库......但它让我从这个愚蠢的问题转移......
希望这有帮助。