From 25f13c4cef13311e97d65914afd2a5eec010e17e Mon Sep 17 00:00:00 2001 From: Shimpei Makimoto Date: Wed, 30 Oct 2013 18:55:52 +0900 Subject: [PATCH 1/2] Prevent irb from crashing when exception with nil backtrace is raised --- lib/irb.rb | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/irb.rb b/lib/irb.rb index 20390d2..a5208a1 100644 --- a/lib/irb.rb +++ b/lib/irb.rb @@ -499,7 +499,7 @@ def eval_input end if exc print exc.class, ": ", exc, "\n" - if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ && + if exc.backtrace && exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ && !(SyntaxError === exc) irb_bug = true else @@ -509,16 +509,18 @@ def eval_input messages = [] lasts = [] levels = 0 - for m in exc.backtrace - m = @context.workspace.filter_backtrace(m) unless irb_bug - if m - if messages.size < @context.back_trace_limit - messages.push "\tfrom "+m - else - lasts.push "\tfrom "+m - if lasts.size > @context.back_trace_limit - lasts.shift - levels += 1 + if exc.backtrace + for m in exc.backtrace + m = @context.workspace.filter_backtrace(m) unless irb_bug + if m + if messages.size < @context.back_trace_limit + messages.push "\tfrom "+m + else + lasts.push "\tfrom "+m + if lasts.size > @context.back_trace_limit + lasts.shift + levels += 1 + end end end end -- 1.8.4 From ae3cc8659b35097634f2b583c2fed38cc768bd13 Mon Sep 17 00:00:00 2001 From: Shimpei Makimoto Date: Wed, 30 Oct 2013 23:09:55 +0900 Subject: [PATCH 2/2] Add test_raise_no_bactrace_exception --- test/irb/test_raise_no_backtrace_exception.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 test/irb/test_raise_no_backtrace_exception.rb diff --git a/test/irb/test_raise_no_backtrace_exception.rb b/test/irb/test_raise_no_backtrace_exception.rb new file mode 100644 index 0000000..e8204d7 --- /dev/null +++ b/test/irb/test_raise_no_backtrace_exception.rb @@ -0,0 +1,14 @@ +require 'test/unit' +require_relative '../ruby/envutil' + +module TestIRB + class TestRaiseNoBacktraceException < Test::Unit::TestCase + def test_raise_exception + status = assert_in_out_err(%w[-rirb -e IRB.start(__FILE__) -- -f --], <<-IRB, /Exception: foo/, []) + e = Exception.new("foo") + def e.backtrace; nil; end + raise e +IRB + end + end +end -- 1.8.4