ConradIrwin / pry-rescue

Start a pry session whenever something goes wrong.
MIT License
852 stars 49 forks source link

Stack Overflow results in crash instead of SystemStackError #66

Open jherman3 opened 10 years ago

jherman3 commented 10 years ago

In pry, if I purposely overflow the stack with infinite recursion, the expected exception is raised:

[1] pry(main)> def crash;crash;end
=> :crash
[2] pry(main)> crash
SystemStackError: stack level too deep

However, if pry-rescue is installed, the following happens, and pry crashes to the shell

[1] pry(main)> def crash;crash;end
=> :crash
[2] pry(main)> crash
/home/user/.rvm/gems/ruby-2.1.0/gems/pry-0.9.12.6/lib/pry/pry_instance.rb:523:in `attr_accessor': can't modify frozen Class (RuntimeError)
vincentwoo commented 10 years ago

This one's interesting. Do you have any leads on why this might be the case?

kyrylo commented 10 years ago

This is fixed with the most recent Pry version: gem install pry -v 0.10.0.pre2. I don't know what exactly fixed it, because there was a lot of commits.

vincentwoo commented 8 years ago

This is happening for me again, now:

root@ac6fb7242f86:~# pry
[1] pry(main)> def crash;crash;end
=> :crash
[2] pry(main)> crash
/var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/last_exception.rb:54:in `bt_source_location_for': undefined method `[]' for nil:NilClass (NoMethodError)
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/last_exception.rb:15:in `initialize'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:494:in `new'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:494:in `last_exception='
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:331:in `rescue in handle_line'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:317:in `handle_line'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:242:in `catch'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:242:in `block in eval'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:241:in `catch'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_instance.rb:241:in `eval'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/repl.rb:77:in `block in repl'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/repl.rb:67:in `loop'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/repl.rb:67:in `repl'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/repl.rb:38:in `block in start'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/input_lock.rb:61:in `__with_ownership'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/input_lock.rb:79:in `with_ownership'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/repl.rb:38:in `start'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/repl.rb:15:in `start'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/pry_class.rb:169:in `start'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/cli.rb:219:in `block in <top (required)>'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `block in parse_options'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `each'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/lib/pry/cli.rb:83:in `parse_options'
    from /var/lib/gems/2.3.0/gems/pry-0.10.3/bin/pry:16:in `<top (required)>'
    from /usr/local/bin/pry:23:in `load'
    from /usr/local/bin/pry:23:in `<main>'
root@ac6fb7242f86:~# pry --version
Pry version 0.10.3 on Ruby 2.3.0
root@ac6fb7242f86:~# gem list

*** LOCAL GEMS ***

awesome_print (1.6.1)
bigdecimal (1.2.8)
coderay (1.1.0)
diff-lcs (1.2.5)
interception (0.5)
io-console (0.4.5)
json (1.8.3)
method_source (0.8.2)
minitest (5.8.4)
pry (0.10.3)
pry-doc (0.8.0)
pry-rescue (1.4.2)
psych (2.0.17)
rdoc (4.2.1)
rspec (3.4.0)
rspec-core (3.4.1)
rspec-expectations (3.4.0)
rspec-mocks (3.4.1)
rspec-support (3.4.1)
slop (3.6.0)
yard (0.8.7.6)
vincentwoo commented 8 years ago

Also, trying to run pry-rescue against a file that has a stack overflow error causes some weird fatal reentry error:

vwoo:rescuetest vwoo$ bundle exec rescue test.rb
WARNING: Tried to inspect exception outside of Pry::rescue{ }
/Users/vwoo/pry-rescue/lib/pry-rescue/core_ext.rb:20:in `rescue in block (2 levels) in rescue': exception reentered (fatal)
    from /Users/vwoo/pry-rescue/lib/pry-rescue/core_ext.rb:15:in `block (2 levels) in rescue'
    from /Users/vwoo/pry-rescue/lib/pry-rescue/core_ext.rb:14:in `catch'
    from /Users/vwoo/pry-rescue/lib/pry-rescue/core_ext.rb:14:in `block in rescue'
    from /Users/vwoo/pry-rescue/lib/pry-rescue/core_ext.rb:13:in `loop'
    from /Users/vwoo/pry-rescue/lib/pry-rescue/core_ext.rb:13:in `rescue'
    from /Users/vwoo/pry-rescue/lib/pry-rescue.rb:75:in `load'
    from /Users/vwoo/pry-rescue/bin/rescue:49:in `<top (required)>'
    from /Users/vwoo/.gem/ruby/2.3.0/bin/rescue:23:in `load'
    from /Users/vwoo/.gem/ruby/2.3.0/bin/rescue:23:in `<main>'

test.rb:

def crash
  crash
end

crash

@ConradIrwin: any thoughts? this one is pretty tricky.

ConradIrwin commented 8 years ago

There used to be a guard in the code to avoid calling any methods if the exception was a stack overflow — someone should try and find that code and check whether it works ;)

vincentwoo commented 8 years ago

https://github.com/ConradIrwin/pry-rescue/blob/master/lib/pry-rescue/core_ext.rb#L42 tries to catch SystemStackError, but at that point it is already a fatal for me. I guess what you're saying is that post rescue if any method is executed at all, we'll fatal out?