During thread cleanup, if a ruby sampling profiler calls thread_profile_frames at just the wrong time, the ec's stack is cleared but the CFP still exists on the EC, so thread_profile_frames assumes it can walk the stack and crashes.
In rb_ec_clear_vm_stack, it should set cfp to NULL before clearing the stack. If during rc_ec_clear_vm_stack the process gets a signal and this thread handles it and calls thread_profile_frames, the early return check of if (!cfp) fails, it continues and crashes in this function.
thread_cleanup: set CFP to NULL before clearing ec's stack
We clear the CFP first so that if a sampling profiler interrupts the current thread during rb_ec_set_vm_stack, thread_profile_frames returns early instead of trying to walk the stack that's no longer set on the ec.
The early return in thread_profile_frames was introduced at eab7f4623fb.