Project

General

Profile

Actions

Bug #22434

closed

"No live threads left. Deadlock?" when running system() or spawn in Ractors

Bug #22434: "No live threads left. Deadlock?" when running system() or spawn in Ractors

Added by jhawthorn (John Hawthorn) 22 days ago. Updated 16 days ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:127096]

Description

Non-main Ractors don't support fork(), but do support system() and spawn(). They can end up deadlocked inside the prefork method when trying to flush stdio.

$stdout = File.open(File::NULL, "w")
writer = Thread.new { loop { $stdout.write("x" * 100 + "\n"); $stdout.flush } }
r = Ractor.new { 500.times { system("true") }; :done }
raise unless :done == r.value
writer.kill.join
❯ ruby -v test.rb
ruby 4.0.7 (2026-09-15 revision 229531a6cf) +PRISM [arm64-darwin25]
test.rb:3: warning: Ractor API is experimental and may change in future versions of Ruby.
#<Thread:0x000000010c1f62a8 run> terminated with exception (report_on_exception is true):
test.rb:3:in 'Kernel#system': No live threads left. Deadlock? (fatal)
1 threads, 1 sleeps current:0x00000007e696b800 main thread:0x00000007e696b800
* #<Thread:0x000000010c1f62a8 sleep_forever>
   rb_thread_t:0x00000007e696b800 native:0x000000016bcef000 int:0
   test.rb:3:in 'Kernel#system'
   test.rb:3:in 'block (2 levels) in <main>'
   test.rb:3:in 'Integer#times'
   test.rb:3:in 'block in <main>'
...

https://github.com/ruby/ruby/pull/19321

Updated by jhawthorn (John Hawthorn) 18 days ago Actions #1

  • Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: REQUIRED to 3.3: WONTFIX, 3.4: WONTFIX, 4.0: REQUIRED

Updated by jhawthorn (John Hawthorn) 16 days ago Actions #2

  • Status changed from Open to Closed

Applied in changeset git|28f2eae4cf7681be36c3011a423154e45d21721c.


Flush the current Ractor's stdout/stderr before spawning

prefork() flushed rb_stdout and rb_stderr, which are the main Ractor's IOs.
From another Ractor that takes the write_lock of an IO the Ractor does not
own. When a main Ractor thread holds it (any thread logging to $stdout will
do), the spawning Ractor's only thread sleeps on the mutex and
rb_check_deadlock, which only looks at the Ractor's own threads, raises
"No live threads left. Deadlock?" (fatal) from Kernel#spawn/system/popen.

Use rb_ractor_stdout()/rb_ractor_stderr() so each Ractor flushes its own.

[Bug #22434]

Actions

Also available in: PDF Atom