The following code ends up an infinite loop
GC.stress = true
t = Thread.new do
temp = Tempfile.new("tmp")
temp << "something"
temp = nil
h = Hash.new
Our analysis shows that there is a race condition in REE 1.8.7:
- When a thread finishes running, REE/Ruby dequeues it
(rb_thread_remove) from the global thread list and calls
rb_thread_schedule in order to schedule another thread to run.
- rb_thread_schedule invokes rb_gc_finalize_deferred before
scheduling another thread.
- rb_gc_finalize calls finalizer on Ruby Tempfile object. The
finalizer closes a file descriptor by calling rb_thread_fd_close
- rb_thread_fd_close has a loop to iterate over all threads.
- However, the current thread is already dequeued (it points to other
threads, but no threads point back to it), so the loop is actually an
We believe this issue also exists in regular Ruby 1.8.7, but we cannot
reproduce it. Is this a bug in REE 1.8.7?