Closed ysbaddaden closed 8 months ago
Creating another context and spawning into that context won't lead to a crash (whatever if the default context is MT or ST):
require "execution_context"
mtx = ExecutionContext::MultiThreaded.new("MTX", size: 9)
5000.times do |i|
mtx.spawn { print "iteration #{i}\n" }
end
I can create 3 execution contexts and it still won't crash. But as soon as I start spawning inside the default context, then I immediately hit the invalid stack stop and the segfault.
Adding a Fiber.yield
every N iterations in the loop will also avoid the segfault (tested with N <= 2000, with N = 4000 it will segfault):
require "execution_context"
mtx = ExecutionContext::MultiThreaded.new("MTX", size: 9)
5000.times do |i|
mtx.spawn { print "iteration #{i}\n" }
Fiber.yield if i % 2000 == 0
end
I enqueue the main fiber loop when hijacking the main thread, which means that any scheduler could steal and resume the run loop of the main thread's scheduler :facepalm:
The following program will crash during a GC collection because of an invalid
#stack_top
in a fiber stack (it's not within the fiber's stack top/bottom), but only when the default context is MT (set the-Dmt
flag).