Skip to content

Commit

Permalink
Set rb_ext_ractor_safe(true) to avoid breakages from removing loader
Browse files Browse the repository at this point in the history
This was an interesting one... Once we removed the profiling loader
extension, our tests using Ractors started failing with:

> Ractor::UnsafeError: ractor unsafe method called from not main ractor

When I started investigating with gdb, I discovered that because
we were initializing our extension without going through Ruby,
we were skipping this part:

https://github.com/ruby/ruby/blob/7178593558080ca529abb61ef27038236ab2687d/load.c#L1301-L1302 :

```c
ext_config_push(th, &prev_ext_config);
handle = rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
                          path, VM_BLOCK_HANDLER_NONE, path);
```

that is, the `ext_config_push` is what's used by Ruby to validate
if a gem is safe to use from Ractors or not. (If you're curious,
that value then affects function definition, which controls
wether Ruby will check or not for being called from a Ractor).

Because we were skipping this entire mechanism, we implicitly
were getting the same result as `rb_ext_ractor_safe(true)`.

Once we removed the loader, this started failing. And I missed it
before opening my PR since for reasons documented in the profiler
ractor tests in detail, we don't run ractor-related tests by
default.

So this issue is one more reason why having the loader may create
its own set of issues and why I'm happy to get rid of it.
  • Loading branch information
ivoanjo committed Feb 7, 2025
1 parent 6a3e147 commit afa07de
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions ext/datadog_profiling_native_extension/profiling.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ static VALUE _native_malloc_stats(DDTRACE_UNUSED VALUE _self);
static VALUE _native_safe_object_info(DDTRACE_UNUSED VALUE _self, VALUE obj);

void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
// The profiler still has a lot of limitations around being used in Ractors BUT for now we're choosing to take care of those
// on our side, rather than asking Ruby to block calling our APIs from Ractors.
rb_ext_ractor_safe(true);

VALUE datadog_module = rb_define_module("Datadog");
VALUE profiling_module = rb_define_module_under(datadog_module, "Profiling");
VALUE native_extension_module = rb_define_module_under(profiling_module, "NativeExtension");
Expand Down

0 comments on commit afa07de

Please sign in to comment.