* compile.c (tailcallable_p): disable tail call optimization for

toplevel, eval, and load to avoid SEGV when interrupted by SIGINT.
  [ruby-core:76327] [Bug #12576]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2016-11-05 16:42:27 +00:00
parent b0569e3dde
commit 11c37ed390
3 changed files with 37 additions and 0 deletions

View File

@ -1,3 +1,9 @@
Sun Nov 6 01:39:36 2016 Shugo Maeda <shugo@ruby-lang.org>
* compile.c (tailcallable_p): disable tail call optimization for
toplevel, eval, and load to avoid SEGV when interrupted by SIGINT.
[ruby-core:76327] [Bug #12576]
Sun Nov 6 01:28:41 2016 Koichi Sasada <ko1@atdot.net>
* vm_insnhelper.h: rename REG_(CFP|PC|SP|EP) to VM_REG_....

View File

@ -2423,6 +2423,10 @@ static inline int
tailcallable_p(rb_iseq_t *iseq)
{
switch (iseq->body->type) {
case ISEQ_TYPE_TOP:
case ISEQ_TYPE_EVAL:
case ISEQ_TYPE_MAIN:
/* not tail callable because cfp will be over popped */
case ISEQ_TYPE_RESCUE:
case ISEQ_TYPE_ENSURE:
/* rescue block can't tail call because of errinfo */

View File

@ -316,6 +316,33 @@ class TestRubyOptimization < Test::Unit::TestCase
message(bug12565) {disasm(:add_one_and_two)})
end
def test_tailcall_interrupted_by_sigint
bug = 'ruby-core:76327'
script = <<EOS
RubyVM::InstructionSequence.compile_option = {
:tailcall_optimization => true,
:trace_instruction => false
}
eval <<EOF
def foo
foo
end
foo
EOF
EOS
err = EnvUtil.invoke_ruby([], "", true, true, {}) {
|in_p, out_p, err_p, pid|
in_p.write(script)
in_p.close
sleep(1)
Process.kill(:SIGINT, pid)
Process.wait(pid)
err_p.read
}
assert_match(/Interrupt/, err, bug)
end
class Bug10557
def [](_)
block_given?