How do I configure ruby to enter the debugger on Ctrl-C (SIGINT)?

debugging, ruby, sigint, signals

Solution

If you want to trap SIGINT while running in the console, the short answer is: you cannot unless you monkey-patch IRB. Every Ruby app (whether padrino, or rails or whatnot) that uses the console will end up calling `usr/lib/ruby/1.9.1/irb.rb`, and in `IRB.start`, it does:

trap("SIGINT") do
  irb.signal_handle
end

... just before entering the main loop. This will override any trap("SIGINT") you might have put in your startup code.

But if you want to trap SIGINT in a script file (for example, if you want to profile your code as described by Mike Dunlavey here), you can create a script file such as:

# File: profile_complex_operation.rb
trap("SIGINT") { debugger }
MyApp.complex_operation

and then invoke it as in:

$ ruby profile_complex_operation.rb

Now, when you hit ^C (or send SIGINT from another process), it will enter the debugger.

Problem

I'd like to enter the debugger upon typing ctrl-C (or sending a SIGINT). I have installed the debugger (I'm running Ruby 1.9.3) and verified that it works. I've added this to my setup files (this is for Padrino, but I assume it would be similar for Rails): ``` # file: config/boot.rb Padrino.before_load do trap("SIGINT") { debugger } if Padrino.env == :development end ``` ... but typing Ctrl-C does not invoke the debugger. In fact, if I replace `debugger` with `puts "saw an interrupt!"`, typing Ctrl-C doesn't cause a print to happen either. update Following this suggestion from Mike Dunlavey, I tried explicitly calling `catch Interrupt` from within the debugger: ``` $ 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> ``` No joy -- interrupt did not enter the debugger. What am I missing?

Original source

Related problems