diff options
-rw-r--r-- | lib/pry/pry_class.rb | 13 | ||||
-rw-r--r-- | spec/pry_spec.rb | 25 |
2 files changed, 38 insertions, 0 deletions
diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 651cf67e..f5f8db6a 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -168,6 +168,12 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc. return end + unless mutex_available? + output.puts "ERROR: Unable to obtain mutex lock." + output.puts "This can happen if binding.pry is called from a signal handler" + return + end + options[:target] = Pry.binding_for(target || toplevel_binding) initial_session_setup final_session_setup @@ -378,6 +384,13 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly ensure Thread.current[:pry_critical_section] -= 1 end + + def self.mutex_available? + Mutex.new.synchronize { true } + rescue ThreadError + false + end + private_class_method :mutex_available? end Pry.init diff --git a/spec/pry_spec.rb b/spec/pry_spec.rb index 1ea0210d..f5bb0713 100644 --- a/spec/pry_spec.rb +++ b/spec/pry_spec.rb @@ -184,6 +184,31 @@ describe Pry do .to raise_error SignalException end + describe "inside signal handler" do + before do + if Pry::Helpers::Platform.jruby? + skip "jruby allows mutex usage in signal handlers" + end + + if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.0.0") + skip "pre-2.0 mri allows mutex usage in signal handlers" + end + + trap("USR1") { @str_output = mock_pry } + end + + after do + trap("USR1") do + # do nothing + end + end + + it "should return with error message" do + Process.kill("USR1", Process.pid) + expect(@str_output).to match(/Unable to obtain mutex lock/) + end + end + describe "multi-line input" do it "works" do expect(mock_pry('x = ', '1 + 4')).to match(/5/) |