diff options
author | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-12-12 18:43:42 +0000 |
---|---|---|
committer | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-12-12 18:43:42 +0000 |
commit | 6af5f650ad00a81144cbc664f86dcfe90437ffb7 (patch) | |
tree | 72d698e12f3c39e6fdc66bd333a8bbebdd62172c | |
parent | 223f760200d0c96c841c267831260e62ebd53b51 (diff) | |
download | ruby-6af5f650ad00a81144cbc664f86dcfe90437ffb7.tar.gz |
Set Thread.report_on_exception=true by default to report exceptions in Threads
* [Feature #14143] [ruby-core:83979]
* vm.c (vm_init2): Set Thread.report_on_exception to true.
* thread.c (thread_start_func_2): Add indication the message is caused
by report_on_exception = true.
* spec/ruby: Specify the new behavior.
* test/ruby/test_thread.rb: Adapt and improve tests for
Thread.report_on_exception and Thread#report_on_exception.
* test/ruby/test_thread.rb, test/ruby/test_exception.rb: Unset
report_on_exception for tests expecting no extra output.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61183 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | spec/ruby/core/thread/report_on_exception_spec.rb | 12 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 1 | ||||
-rw-r--r-- | test/ruby/test_thread.rb | 43 | ||||
-rw-r--r-- | thread.c | 2 | ||||
-rw-r--r-- | vm.c | 1 |
5 files changed, 42 insertions, 17 deletions
diff --git a/spec/ruby/core/thread/report_on_exception_spec.rb b/spec/ruby/core/thread/report_on_exception_spec.rb index 4128dad470..74b7984a32 100644 --- a/spec/ruby/core/thread/report_on_exception_spec.rb +++ b/spec/ruby/core/thread/report_on_exception_spec.rb @@ -2,8 +2,16 @@ require File.expand_path('../../../spec_helper', __FILE__) ruby_version_is "2.4" do describe "Thread.report_on_exception" do - it "defaults to false" do - ruby_exe("p Thread.report_on_exception").should == "false\n" + ruby_version_is "2.4"..."2.5" do + it "defaults to false" do + ruby_exe("p Thread.report_on_exception").should == "false\n" + end + end + + ruby_version_is "2.5" do + it "defaults to true" do + ruby_exe("p Thread.report_on_exception").should == "true\n" + end end end diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index ce3e98f2c8..fab6ec9f0f 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -354,6 +354,7 @@ class TestException < Test::Unit::TestCase def test_thread_signal_location _, stderr, _ = EnvUtil.invoke_ruby(%w"--disable-gems -d", <<-RUBY, false, true) Thread.start do + Thread.current.report_on_exception = false begin Process.kill(:INT, $$) ensure diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 9242f7f480..ed22249091 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -317,7 +317,10 @@ class TestThread < Test::Unit::TestCase assert_in_out_err([], <<-INPUT, %w(false 1), []) p Thread.abort_on_exception begin - t = Thread.new { raise } + t = Thread.new { + Thread.current.report_on_exception = false + raise + } Thread.pass until t.stop? p 1 rescue @@ -329,7 +332,10 @@ class TestThread < Test::Unit::TestCase Thread.abort_on_exception = true p Thread.abort_on_exception begin - Thread.new { raise } + Thread.new { + Thread.current.report_on_exception = false + raise + } sleep 0.5 p 1 rescue @@ -352,7 +358,11 @@ class TestThread < Test::Unit::TestCase p Thread.abort_on_exception begin ok = false - t = Thread.new { Thread.pass until ok; raise } + t = Thread.new { + Thread.current.report_on_exception = false + Thread.pass until ok + raise + } t.abort_on_exception = true p t.abort_on_exception ok = 1 @@ -370,17 +380,20 @@ class TestThread < Test::Unit::TestCase q1 = Thread::Queue.new q2 = Thread::Queue.new - assert_equal(false, Thread.report_on_exception, - "global flags is false by default") - assert_equal(false, Thread.current.report_on_exception) + assert_equal(true, Thread.report_on_exception, + "global flag is true by default") + assert_equal(false, Thread.current.report_on_exception, + "the main thread has report_on_exception=false") - Thread.current.report_on_exception = true - assert_equal(false, + Thread.report_on_exception = true + Thread.current.report_on_exception = false + assert_equal(true, Thread.start {Thread.current.report_on_exception}.value, - "should not inherit from the parent thread") + "should not inherit from the parent thread but from the global flag") - assert_warn("", "exception should be ignored silently") { + assert_warn("", "exception should be ignored silently when false") { th = Thread.start { + Thread.current.report_on_exception = false q1.push(Thread.current.report_on_exception) raise "report 1" } @@ -388,7 +401,7 @@ class TestThread < Test::Unit::TestCase Thread.pass while th.alive? } - assert_warn(/report 2/, "exception should be reported") { + assert_warn(/report 2/, "exception should be reported when true") { th = Thread.start { q1.push(Thread.current.report_on_exception = true) raise "report 2" @@ -397,8 +410,8 @@ class TestThread < Test::Unit::TestCase Thread.pass while th.alive? } - assert_equal(false, Thread.report_on_exception) assert_warn("", "the global flag should not affect already started threads") { + Thread.report_on_exception = false th = Thread.start { q2.pop q1.push(Thread.current.report_on_exception) @@ -409,8 +422,8 @@ class TestThread < Test::Unit::TestCase Thread.pass while th.alive? } - assert_equal(true, Thread.report_on_exception) assert_warn(/report 4/, "should defaults to the global flag at the start") { + Thread.report_on_exception = true th = Thread.start { q1.push(Thread.current.report_on_exception) raise "report 4" @@ -419,7 +432,7 @@ class TestThread < Test::Unit::TestCase Thread.pass while th.alive? } - assert_warn(/report 5/, "should defaults to the global flag at the start") { + assert_warn(/report 5/, "should first report and then raise with report_on_exception + abort_on_exception") { th = Thread.start { Thread.current.report_on_exception = true Thread.current.abort_on_exception = true @@ -780,6 +793,7 @@ class TestThread < Test::Unit::TestCase th_waiting = true t = Thread.new { + Thread.current.report_on_exception = false Thread.handle_interrupt(RuntimeError => :on_blocking) { nil while th_waiting # async interrupt should be raised _before_ writing puts arguments @@ -800,6 +814,7 @@ class TestThread < Test::Unit::TestCase th_waiting = false t = Thread.new { + Thread.current.report_on_exception = false Thread.handle_interrupt(RuntimeError => :on_blocking) { th_waiting = true nil while th_waiting @@ -648,7 +648,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s else { if (th->report_on_exception) { VALUE mesg = rb_thread_to_s(th->self); - rb_str_cat_cstr(mesg, " terminated with exception:\n"); + rb_str_cat_cstr(mesg, " terminated with exception (report_on_exception is true):\n"); rb_write_error_str(mesg); rb_ec_error_print(th->ec, errinfo); } @@ -2280,6 +2280,7 @@ vm_init2(rb_vm_t *vm) { MEMZERO(vm, rb_vm_t, 1); rb_vm_living_threads_init(vm); + vm->thread_report_on_exception = 1; vm->src_encoding_index = -1; vm_default_params_setup(vm); |