Project

General

Profile

Bug #15385

Ruby process hang in ensure

Added by pawelpacana (Paweł Pacana) almost 2 years ago. Updated over 1 year 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

Updated by ujihisa (Tatsuhiro Ujihisa) almost 2 years 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) almost 2 years 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) almost 2 years ago

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

Updated by nobu (Nobuyoshi Nakada) almost 2 years 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) almost 2 years 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) over 1 year ago

Memo: r61591, r61592, r66324 are related.

#8

Updated by usa (Usaku NAKAMURA) over 1 year ago

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

Also available in: Atom PDF