From: "jhawthorn (John Hawthorn) via ruby-core" Date: 2026-06-11T08:20:19+00:00 Subject: [ruby-core:125691] [Ruby Bug#22098] RUBY_INTERNAL_THREAD_EVENT_RESUMED runs without GVL held Issue #22098 has been updated by jhawthorn (John Hawthorn). Subject changed from THREAD_EVENT_RESUMED runs without GVL held to RUBY_INTERNAL_THREAD_EVENT_RESUMED runs without GVL held Eregon (Benoit Daloze) wrote in #note-10: > Since the hook is called after the GVL is acquired, one would expect to be able to run regular Ruby code there. I feel very strongly that we must not allow arbitrary Ruby code in these hooks. Arbitrary Ruby code may release the GVL and so that would require these hooks to deal with reentrancy, which is a really bad idea. As a subscriber to this API (as a profiler) I need the guarantee that these events are delivered reliably and in order (for the given thread). It's not acceptable that an earlier subscriber delays and changes the order in which events are delivered, breaking the documented invariants of the GVL state machine (ex. if we re-suspend in a hook the hook after it will see the SUSPENDED event before the previous RESUMED, will later see multiple RESUMED in a row). We could detect re-entrancy and disable the hooks (as tracepoint does), I really do not want that. It's important for my profiler to have accurate delivery of all events. This is a very low level API and we should expect consumers to all be careful and well behaved. **At best** a limited selection of Ruby APIs could be made safe to use here (currently all are unsafe). We _could_ probably support allocation here (through the rewrite discussed above to call the hooks later from N different locations). I don't think we should. To support allocations we need to make `ruby_thread_has_gvl_p()` return true. However we're in some intermediate "you have the GVL but releasing it is illegal" state that is going to result with buggy instrumentation extensions (like we just found). With the current state where `ruby_thread_has_gvl_p()` returns false, we can at least still detect these bugs via assertions. IMO the INTERNAL thread event API should adopt the [same warning in documentation the INTERNAL tracepoint events have](https://github.com/ruby/ruby/blob/master/include/ruby/debug.h#L402-L407). It effectively has this restriction for all events _except_ for RUBY_INTERNAL_THREAD_EVENT_RESUMED. > You can use any Ruby APIs (calling methods and so on) on normal event hooks. > **However, in internal events, you can not use any Ruby APIs (even object creations).** ---------------------------------------- Bug #22098: RUBY_INTERNAL_THREAD_EVENT_RESUMED runs without GVL held https://bugs.ruby-lang.org/issues/22098#change-117553 * Author: luke-gru (Luke Gruber) * Status: Open * Assignee: luke-gru (Luke Gruber) * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Today, it's possible to get a deadlock when allocating during a hook for this event. I attached a reproduction script using the `gvltools` gem. One way to fix it would be to not allocate during this hook and change the documentation to be clear that the GVL is not held. Any gems relying on this behavior, like `gvltools`, would need to be patched. Another way to approach it would be to change the call site for this hook invocation. I believe it would need to be added to quite a few places. To maintain Ractor safety, it would also need to be invoked without any locks held. I'm curious about your thoughts @byroot. ---Files-------------------------------- repro.rb (3.11 KB) run_loop.sh (2.82 KB) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/