如何配置ruby以在Ctrl-C(SIGINT)上进入调试器?
我想在输入ctrl-C(或发送SIGINT)时进入调试器。 我已经安装了调试器 (我正在运行Ruby 1.9.3)并validation它是否有效。 我已将此添加到我的安装文件中(这适用于Padrino,但我认为它与Rails类似):
# file: config/boot.rb Padrino.before_load do trap("SIGINT") { debugger } if Padrino.env == :development end
…但是键入Ctrl-C不会调用调试器。 事实上,如果我用puts "saw an interrupt!"
替换debugger
puts "saw an interrupt!"
,键入Ctrl-C也不会导致打印。
更新
根据Mike Dunlavey的 这个建议 ,我尝试在调试器中显式调用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> Cc Cc^C irb(main):001:0>
没有欢乐 – 中断没有进入调试器。
我错过了什么?
如果你想在控制台中运行时捕获SIGINT,简短的答案是:除非你修补IRB,否则你不能。 每个使用控制台的Ruby应用程序(无论是padrino,rails还是whatnot)最终都会调用usr/lib/ruby/1.9.1/irb.rb
,而在IRB.start
,它会:
trap("SIGINT") do irb.signal_handle end
……就在进入主循环之前。 这将覆盖您在启动代码中放置的任何陷阱(“SIGINT”)。
但是如果你想在一个脚本文件中捕获SIGINT(例如,如果你想按照Mike Dunlavey的描述来描述你的代码),你可以创建一个脚本文件,例如:
# File: profile_complex_operation.rb trap("SIGINT") { debugger } MyApp.complex_operation
然后调用它,如:
$ ruby profile_complex_operation.rb
现在,当你点击^ C(或从另一个进程发送SIGINT)时,它将进入调试器。
您可以尝试使用GDB包装器来实现Ruby ( GitHub )。
通过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
然后:
# 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\//}
来源: 使用gdb检查挂起的ruby进程
一些替代品:
- rbtrace – 类似于strace,但是对于ruby代码(用法:
rbtrace -p
)。--firehose - tmm1 (gdb.rb的作者)的debug.rb脚本,它可以帮助使用strace / gdb调试进程。
也可以看看:
- 调试Ruby工具
- 检查为什么ruby脚本挂起