irb icon indicating copy to clipboard operation
irb copied to clipboard

Ctrl-C stops working after using binding.irb

Open aycabta opened this issue 5 years ago • 3 comments

When using binding.irb, subsequent use of SIGINT fails.

current = Signal.trap(:INT) {puts "Handled"}

Process.kill(:INT, Process.pid)

binding.irb

Process.kill(:INT, Process.pid)

Gives:

Handled

From: /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/320667e1-6291-4143-979c-a113e661d440 @ line 5 :

    1: current = Signal.trap(:INT) {puts "Handled"}
    2: 
    3: Process.kill(:INT, Process.pid)
    4: 
 => 5: binding.irb
    6: 
    7: Process.kill(:INT, Process.pid)
    8: 

irb(main):001:0> ^D

Using the following code:

binding.irb

current = Signal.trap(:INT) {puts "Handled"}

puts current.inspect

...we can see the signal is not restored:

From: /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/fe62f3b3-200b-4bbb-926d-c6686dad1d93 @ line 1 :

 => 1: binding.irb
    2: 
    3: current = Signal.trap(:INT) {puts "Handled"}
    4: 
    5: puts current.inspect
irb(main):001:0> 
#<Proc:0x00007fb8648481d0 /Users/samuel/.rubies/ruby-2.7.1/lib/ruby/2.7.0/irb.rb:465>

aycabta avatar Apr 16 '20 05:04 aycabta

Here is an example of how to use signals which avoids leaking changes:

begin
  previous_handler = Signal.trap(:INT) {puts "Handled"}
  sleep 5
ensure
  puts "Restoring original handler: #{previous_handler}"
  Signal.trap(:INT, previous_handler)
  sleep 5
end

ioquatix avatar Apr 16 '20 05:04 ioquatix

I am facing this with Ruby 2.7.1 and Puma 4.3.3. After invoking binding.irb I am unable to kill the puma server. Any solutions or workarounds that I can try?

sriranggd avatar Nov 10 '21 12:11 sriranggd

looks like for some recent versions of rubies this issue should be fixed here: https://github.com/ruby/irb/blob/master/lib/irb.rb#L485 for the cases when it's not fixed this workaround may help:

# fixes Ctrl+C issue with puma web server
# (e.g. after binding.irb invocation Ctrl+C stops working)
class Binding
  alias __orig_irb irb

  def irb
    previous_handler = Signal.trap(:INT) {} # rubocop:disable Lint/EmptyBlock

    __orig_irb # binding.irb sets up it's own SIGINT handler

    Signal.trap(:INT, previous_handler)
  end
end

place it somewhere at the end of config/environments/development.rb (for rails apps)

NOTE: it's quick and dirty stuff, not recommended for production usage

kucaahbe avatar Jan 07 '22 11:01 kucaahbe

Looks like this is fixed in irb-1.3.5

tompng avatar Aug 14 '24 17:08 tompng

Thanks @tompng, binding.irb is so great now!

ioquatix avatar Aug 14 '24 22:08 ioquatix