Disable callcc when ASAN is enabled

callcc's implementation is fundamentally incompatible with ASAN. Since
callcc is deprecated and almost never used, it's probably OK to disable
callcc when ruby is compiled with ASAN.

[Bug #20273]
This commit is contained in:
KJ Tsanaktsidis 2024-02-17 17:30:34 +11:00
parent 0d9a681eff
commit 5621d794a2
9 changed files with 47 additions and 15 deletions

7
cont.c
View File

@ -1775,6 +1775,13 @@ rb_callcc(VALUE self)
return rb_yield(val); return rb_yield(val);
} }
} }
#ifdef RUBY_ASAN_ENABLED
/* callcc can't possibly work with ASAN; see bug #20273. Also this function
* definition below avoids a "defined and not used" warning. */
MAYBE_UNUSED(static void notusing_callcc(void)) { rb_callcc(Qnil); }
# define rb_callcc rb_f_notimplement
#endif
static VALUE static VALUE
make_passing_arg(int argc, const VALUE *argv) make_passing_arg(int argc, const VALUE *argv)

View File

@ -3561,6 +3561,7 @@ class TestArray < Test::Unit::TestCase
unless respond_to?(:callcc, true) unless respond_to?(:callcc, true)
EnvUtil.suppress_warning {require 'continuation'} EnvUtil.suppress_warning {require 'continuation'}
end end
omit 'requires callcc support' unless respond_to?(:callcc, true)
end end
end end

View File

@ -1,5 +1,6 @@
# frozen_string_literal: false # frozen_string_literal: false
require 'test/unit' require 'test/unit'
EnvUtil.suppress_warning {require 'continuation'}
class TestBeginEndBlock < Test::Unit::TestCase class TestBeginEndBlock < Test::Unit::TestCase
DIR = File.dirname(File.expand_path(__FILE__)) DIR = File.dirname(File.expand_path(__FILE__))
@ -131,6 +132,8 @@ class TestBeginEndBlock < Test::Unit::TestCase
end end
def test_callcc_at_exit def test_callcc_at_exit
omit 'requires callcc support' unless respond_to?(:callcc)
bug9110 = '[ruby-core:58329][Bug #9110]' bug9110 = '[ruby-core:58329][Bug #9110]'
assert_ruby_status([], "#{<<~"begin;"}\n#{<<~'end;'}", bug9110) assert_ruby_status([], "#{<<~"begin;"}\n#{<<~'end;'}", bug9110)
begin; begin;

View File

@ -4,6 +4,10 @@ EnvUtil.suppress_warning {require 'continuation'}
require 'fiber' require 'fiber'
class TestContinuation < Test::Unit::TestCase class TestContinuation < Test::Unit::TestCase
def setup
omit 'requires callcc support' unless respond_to?(:callcc)
end
def test_create def test_create
assert_equal(:ok, callcc{:ok}) assert_equal(:ok, callcc{:ok})
assert_equal(:ok, callcc{|c| c.call :ok}) assert_equal(:ok, callcc{|c| c.call :ok})

View File

@ -843,6 +843,8 @@ class TestEnumerable < Test::Unit::TestCase
end end
def test_callcc def test_callcc
omit 'requires callcc support' unless respond_to?(:callcc)
assert_raise(RuntimeError) do assert_raise(RuntimeError) do
c = nil c = nil
@obj.sort_by {|x| callcc {|c2| c ||= c2 }; x } @obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }

View File

@ -82,12 +82,14 @@ class TestFiber < Test::Unit::TestCase
f.resume f.resume
f.resume f.resume
} }
assert_raise(RuntimeError){ if respond_to?(:callcc)
Fiber.new{ assert_raise(RuntimeError){
@c = callcc{|c| @c = c} Fiber.new{
}.resume @c = callcc{|c| @c = c}
@c.call # cross fiber callcc }.resume
} @c.call # cross fiber callcc
}
end
assert_raise(RuntimeError){ assert_raise(RuntimeError){
Fiber.new{ Fiber.new{
raise raise

View File

@ -1359,6 +1359,8 @@ class TestHash < Test::Unit::TestCase
end end
def test_callcc def test_callcc
omit 'requires callcc support' unless respond_to?(:callcc)
h = @cls[1=>2] h = @cls[1=>2]
c = nil c = nil
f = false f = false
@ -1379,6 +1381,8 @@ class TestHash < Test::Unit::TestCase
end end
def test_callcc_iter_level def test_callcc_iter_level
omit 'requires callcc support' unless respond_to?(:callcc)
bug9105 = '[ruby-dev:47803] [Bug #9105]' bug9105 = '[ruby-dev:47803] [Bug #9105]'
h = @cls[1=>2, 3=>4] h = @cls[1=>2, 3=>4]
c = nil c = nil
@ -1397,6 +1401,8 @@ class TestHash < Test::Unit::TestCase
end end
def test_callcc_escape def test_callcc_escape
omit 'requires callcc support' unless respond_to?(:callcc)
bug9105 = '[ruby-dev:47803] [Bug #9105]' bug9105 = '[ruby-dev:47803] [Bug #9105]'
assert_nothing_raised(RuntimeError, bug9105) do assert_nothing_raised(RuntimeError, bug9105) do
h=@cls[] h=@cls[]
@ -1411,6 +1417,8 @@ class TestHash < Test::Unit::TestCase
end end
def test_callcc_reenter def test_callcc_reenter
omit 'requires callcc support' unless respond_to?(:callcc)
bug9105 = '[ruby-dev:47803] [Bug #9105]' bug9105 = '[ruby-dev:47803] [Bug #9105]'
assert_nothing_raised(RuntimeError, bug9105) do assert_nothing_raised(RuntimeError, bug9105) do
h = @cls[1=>2,3=>4] h = @cls[1=>2,3=>4]

View File

@ -609,6 +609,8 @@ class TestMarshal < Test::Unit::TestCase
def test_continuation def test_continuation
EnvUtil.suppress_warning {require "continuation"} EnvUtil.suppress_warning {require "continuation"}
omit 'requires callcc support' unless respond_to?(:callcc)
c = Bug9523.new c = Bug9523.new
assert_raise_with_message(RuntimeError, /Marshal\.dump reentered at marshal_dump/) do assert_raise_with_message(RuntimeError, /Marshal\.dump reentered at marshal_dump/) do
Marshal.dump(c) Marshal.dump(c)

View File

@ -1,5 +1,6 @@
# frozen_string_literal: false # frozen_string_literal: false
require 'test/unit' require 'test/unit'
EnvUtil.suppress_warning {require 'continuation'}
class TestSetTraceFunc < Test::Unit::TestCase class TestSetTraceFunc < Test::Unit::TestCase
def setup def setup
@ -1258,15 +1259,17 @@ CODE
end end
} }
assert_normal_exit src % %q{obj.zip({}) {}}, bug7774 assert_normal_exit src % %q{obj.zip({}) {}}, bug7774
assert_normal_exit src % %q{ if respond_to?(:callcc)
require 'continuation' assert_normal_exit src % %q{
begin require 'continuation'
c = nil begin
obj.sort_by {|x| callcc {|c2| c ||= c2 }; x } c = nil
c.call obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
rescue RuntimeError c.call
end rescue RuntimeError
}, bug7774 end
}, bug7774
end
# TracePoint # TracePoint
tp_b = nil tp_b = nil