From 7a127599c8385a1c3794c7788e034c41710a8f9b Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Thu, 14 Mar 2024 19:50:59 +0100 Subject: [PATCH] ruby: register grpc_rb_sStatus as a global variable Ref: https://bugs.ruby-lang.org/issues/20311 C global variable that contain references to Ruby object MUST be declared to the Ruby GC to prevent these objects from being collected or moved. There are a few exceptions to that, such as classes defined using the C APIs such as `rb_define_class` etc. Up to Ruby 3.4 however, there was a bug that caused classes created from Ruby with the `Struct.new("Name")` API to also be marked as immortal and immovable. GRPC has been relying on this bug, which I fixed in Ruby 3.4, and now GRPC is crashing when `Struct::Status` is moved around by the GC. --- src/ruby/ext/grpc/rb_grpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index 4896323bc02..01c4777d800 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -467,6 +467,7 @@ void Init_grpc_c() { grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core"); grpc_rb_sNewServerRpc = rb_struct_define( "NewServerRpc", "method", "host", "deadline", "metadata", "call", NULL); + rb_global_variable(&grpc_rb_sStatus); grpc_rb_sStatus = rb_const_get(rb_cStruct, rb_intern("Status")); sym_code = ID2SYM(rb_intern("code")); sym_details = ID2SYM(rb_intern("details"));