Issue #21926 has been updated by luke-gru (Luke Gruber). A note to whoever backports this (which could be me, I'm just waiting ~ 1 week and checking various CIs after the merge): https://github.com/ruby/ruby/pull/16362 should be backported as well, they are really 1 fix in 2 separate commits. ---------------------------------------- Bug #21926: Thread#value on popen3 wait thread hangs in finalizer https://bugs.ruby-lang.org/issues/21926#change-116664 * Author: stevecrozz (Stephen Crosby) * Status: Closed * Assignee: luke-gru (Luke Gruber) * ruby -v: 3.3.7 * Backport: 3.2: UNKNOWN, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED ---------------------------------------- Calling Thread#value on an Open3.popen3 wait thread from a finalizer completes in Ruby 3.2 but hangs in Ruby 3.3+. See repro.rb below. When the Ruby process hangs in these conditions, it no longer responds to signals and it seems to be unable to run any other threads. This affects the schmooze gem (and potentially other code using Open3.popen3 with finalizers), causing test suites to hang intermittently. ``` ruby # repro.rb require 'open3' class ProcessWrapper def initialize @stdin, @stdout, @stderr, @wait_thread = Open3.popen3("cat") ObjectSpace.define_finalizer(self, self.class.make_finalizer(@stdin, @stdout, @stderr, @wait_thread)) end def self.make_finalizer(stdin, stdout, stderr, wait_thread) proc do stdin.close rescue nil stdout.close rescue nil stderr.close rescue nil wait_thread.value # Hangs here in Ruby 3.3+ end end end 100.times { ProcessWrapper.new } GC.stress = true 1000.times { Object.new } puts "done" ``` ## Environment - Linux x86_64 - Tested on Ruby 3.2.7, 3.3.7, 3.4.8 -- https://bugs.ruby-lang.org/