mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
2406207cbb
commit
5a3c024df0
5 changed files with 42 additions and 17 deletions
|
@ -2,11 +2,19 @@ require File.expand_path('../../../spec_helper', __FILE__)
|
|||
|
||||
ruby_version_is "2.4" do
|
||||
describe "Thread.report_on_exception" do
|
||||
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
|
||||
|
||||
describe "Thread.report_on_exception=" do
|
||||
before :each do
|
||||
@report_on_exception = Thread.report_on_exception
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
2
thread.c
2
thread.c
|
@ -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);
|
||||
}
|
||||
|
|
1
vm.c
1
vm.c
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue