ruby-changes:49068
From: eregon <ko1@a...>
Date: Wed, 13 Dec 2017 03:43:49 +0900 (JST)
Subject: [ruby-changes:49068] eregon:r61183 (trunk): Set Thread.report_on_exception=true by default to report exceptions in Threads
eregon 2017-12-13 03:43:42 +0900 (Wed, 13 Dec 2017) New Revision: 61183 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61183 Log: 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. Modified files: trunk/spec/ruby/core/thread/report_on_exception_spec.rb trunk/test/ruby/test_exception.rb trunk/test/ruby/test_thread.rb trunk/thread.c trunk/vm.c Index: spec/ruby/core/thread/report_on_exception_spec.rb =================================================================== --- spec/ruby/core/thread/report_on_exception_spec.rb (revision 61182) +++ spec/ruby/core/thread/report_on_exception_spec.rb (revision 61183) @@ -2,8 +2,16 @@ require File.expand_path('../../../spec_ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/thread/report_on_exception_spec.rb#L2 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 Index: vm.c =================================================================== --- vm.c (revision 61182) +++ vm.c (revision 61183) @@ -2280,6 +2280,7 @@ vm_init2(rb_vm_t *vm) https://github.com/ruby/ruby/blob/trunk/vm.c#L2280 { 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); Index: test/ruby/test_thread.rb =================================================================== --- test/ruby/test_thread.rb (revision 61182) +++ test/ruby/test_thread.rb (revision 61183) @@ -317,7 +317,10 @@ class TestThread < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L317 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L332 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L358 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L380 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) - - Thread.current.report_on_exception = true - assert_equal(false, + 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.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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L401 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L410 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L422 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L432 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L793 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L814 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 Index: test/ruby/test_exception.rb =================================================================== --- test/ruby/test_exception.rb (revision 61182) +++ test/ruby/test_exception.rb (revision 61183) @@ -354,6 +354,7 @@ class TestException < Test::Unit::TestCa https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L354 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 Index: thread.c =================================================================== --- thread.c (revision 61182) +++ thread.c (revision 61183) @@ -648,7 +648,7 @@ thread_start_func_2(rb_thread_t *th, VAL https://github.com/ruby/ruby/blob/trunk/thread.c#L648 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); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/