Project

General

Profile

Bug #15385

Ruby process hang in ensure

Added by pawelpacana (Paweł Pacana) 12 months ago. Updated 7 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
[ruby-core:90332]

Description

While playing with mutation testing of my code I've found a weird mutation that hangs Ruby process. The isolated code which triggers this freeze is:

require 'timeout'

puts Process.pid

def raise_before_returning
  raise
  []
end

def doh
  value = raise_before_returning
ensure
  # p value # <-- that unblocks it
  value if nil
end

Timeout.timeout(3) do
  doh
end
  1. Timeout is unnecessary and was added to illustrate that it has no effect to interrupt hanged process.
  2. Process.pid is printed for convenience to kill hanged process.
  3. Printing value in ensure changes behavior, there is no hang when encountering value if nil below.

I've also checked ruby 2.6.0preview3 (2018-11-06 trunk 65578) [x86_64-darwin18] and the problem persists.


Files

reproduce.rb (216 Bytes) reproduce.rb reproduction script pawelpacana (Paweł Pacana), 12/06/2018 01:42 AM

Related issues

Related to Ruby master - Bug #14897: Unexpected behavior of `if` in specific codeClosedActions

Associated revisions

Revision b91599c4
Added by nobu (Nobuyoshi Nakada) 12 months ago

Fix infinite loop by ensure

  • compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66326 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 66326
Added by nobu (Nobuyoshi Nakada) 12 months ago

Fix infinite loop by ensure

  • compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385]

Revision 66326
Added by nobu (Nobuyoshi Nakada) 12 months ago

Fix infinite loop by ensure

  • compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385]

Revision bcdcee47
Added by usa (Usaku NAKAMURA) 7 months ago

merge revision(s) 66326,66649: [Backport #15385]

Fix infinite loop by ensure

  • compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385]

test_optimization.rb: increase timeout for RubyCI

https://rubyci.org/logs/rubyci.s3.amazonaws.com/opensuseleap/ruby-trunk/log/20181230T040002Z.fail.html.gz

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 67702
Added by usa (Usaku NAKAMURA) 7 months ago

merge revision(s) 66326,66649: [Backport #15385]

Fix infinite loop by ensure

  • compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385]

test_optimization.rb: increase timeout for RubyCI

https://rubyci.org/logs/rubyci.s3.amazonaws.com/opensuseleap/ruby-trunk/log/20181230T040002Z.fail.html.gz

Revision 6610b77e
Added by usa (Usaku NAKAMURA) 7 months ago

merge revision(s) 66324: [Backport #15385]

    Modify insn list only when compiling

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67708 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 67708
Added by usa (Usaku NAKAMURA) 7 months ago

merge revision(s) 66324: [Backport #15385]

Modify insn list only when compiling

History

Updated by ujihisa (Tatsuhiro Ujihisa) 12 months ago

This reproduces even without timeout library.

def doh
  raise
ensure
  123 if false
end

doh

looks like this is because the optimizer removed if false or if nil without adding nop iseq.

Updated by pawelpacana (Paweł Pacana) 12 months ago

ujihisa (Tatsuhiro Ujihisa) wrote:
looks like this is because the optimizer removed if false or if nil without adding nop iseq.

Could it be related then to https://bugs.ruby-lang.org/issues/14959#note-7 and https://bugs.ruby-lang.org/issues/15392 then?

#4

Updated by shyouhei (Shyouhei Urabe) 12 months ago

  • Related to Bug #14897: Unexpected behavior of `if` in specific code added
#5

Updated by nobu (Nobuyoshi Nakada) 12 months ago

  • Status changed from Open to Closed

Applied in changeset trunk|r66326.


Fix infinite loop by ensure

  • compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385]

Updated by nagachika (Tomoyuki Chikanaga) 12 months ago

  • Backport changed from 2.4: UNKNOWN, 2.5: UNKNOWN to 2.4: REQUIRED, 2.5: REQUIRED

I didn't confirm this can be reproduced on ruby_2_4 too.
After a quick code reading, I think it might be.

Updated by nagachika (Tomoyuki Chikanaga) 10 months ago

Memo: r61591, r61592, r66324 are related.

#8

Updated by usa (Usaku NAKAMURA) 7 months ago

  • Backport changed from 2.4: REQUIRED, 2.5: REQUIRED to 2.4: WONTFIX, 2.5: DONE

Also available in: Atom PDF