如何配置ruby以在Ctrl-C(SIGINT)上进入调试器?

如何配置ruby以在Ctrl-C(SIGINT)上进入调试器?,ruby,debugging,signals,sigint,Ruby,Debugging,Signals,Sigint,我希望在键入ctrl-C(或发送SIGINT)后进入调试器。我已经(运行Ruby 1.9.3)并验证了它的工作原理。我已将其添加到我的安装文件中(这是针对Padrino的,但我认为它与Rails类似): 。。。但是键入Ctrl-C不会调用调试器。事实上,如果我将调试器替换为放置“sawainterrupt!”,那么键入Ctrl-C也不会导致打印 更新 从开始,我尝试在调试器中显式调用catch Interrupt: $ rdebug `which padrino` console ^Z^Z$HO

我希望在键入ctrl-C(或发送SIGINT)后进入调试器。我已经(运行Ruby 1.9.3)并验证了它的工作原理。我已将其添加到我的安装文件中(这是针对Padrino的,但我认为它与Rails类似):

。。。但是键入Ctrl-C不会调用调试器。事实上,如果我将
调试器
替换为
放置“sawainterrupt!”
,那么键入Ctrl-C也不会导致打印

更新 从开始,我尝试在调试器中显式调用
catch Interrupt

$ rdebug `which padrino` console
^Z^Z$HOME/usr/bin/padrino:9
require 'rubygems'
(rdb:1) catch Interrupt
Catch exception Interrupt.
(rdb:1) c
=> Loading development console (Padrino v.0.10.7)
=> Loading Application BlueDotAe
=> Loading Application Admin
irb(main):001:0>   C-c C-c^C
irb(main):001:0> 
没有乐趣——中断没有进入调试器


我遗漏了什么?

如果您想在控制台中运行时捕获SIGINT,简短的回答是:除非您使用monkey补丁IRB,否则无法捕获。每个使用控制台的Ruby应用程序(无论是padrino、rails还是其他)最终都会调用
usr/lib/Ruby/1.9.1/irb.rb
,在
irb.start
,它会:

trap("SIGINT") do
  irb.signal_handle
end
。。。就在进入主循环之前。这将覆盖您可能在启动代码中设置的任何陷阱(“SIGINT”)

但是,如果您想在脚本文件中捕获SIGINT(例如,如果您想按所述评测代码),则可以创建一个脚本文件,例如:

# File: profile_complex_operation.rb
trap("SIGINT") { debugger }
MyApp.complex_operation
然后调用它,如中所示:

$ ruby profile_complex_operation.rb
现在,当您点击^C(或从另一个进程发送SIGINT)时,它将进入调试器。

您可以尝试使用()

通过以下方式在Linux上安装:

sudo apt-get install gdb python-dev ncurses-dev ruby-rvm
gem install gdb.rb
基本用法:

require 'gdb'

# create a new GDB::Ruby instance and attach it to
# pid 12345
gdb = GDB::Ruby.new(12345)

# print the (ruby) backtrace of the remote process
gdb.backtrace.each { |line| puts line }

# show the current local variables, and their values
p gdb.local_variables

# evaluate arbitrary ruby code in the remote process
p gdb.eval('%(pid #{$$})')

# show how many instances of each class exist in the
# remote process
p gdb.object_space

# raise an exception in the remote process
gdb.raise Exception, "go boom!"

# close the connection to the remote process
gdb.quit
或者,要调试挂起的进程,请通过以下方式连接它:

rvmsudo gdb.rb PID
然后:

资料来源:

一些备选方案:

  • -类似于strace,但适用于ruby代码(用法:
    rbtrace-p--firehouse
  • tmm1(gdb.rb的作者)编写的脚本,它可以帮助使用strace/gdb调试进程
另见:


只是澄清一点-使用此方法,当您进入调试器时,您是在陷阱点还是在发送
SIGINT
时在代码执行点输入调用堆栈?
rvmsudo gdb.rb PID
# in gdb get a ruby stacktrace with file names and line numbers
# here I'm filtering by files that are actually in my app dir
(gdb) ruby eval caller.select{|l| l =~ /app\//}