grpc/src/ruby
Jean byroot Boussier 930b3934bc ruby: register grpc_rb_sStatus as a global variable (#36125)
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.

```
-- C level backtrace information -------------------------------------------
ruby(rb_print_backtrace+0x14) [0x5577db219d41] ruby-3.4.0/vm_dump.c:820
ruby(rb_vm_bugreport) ruby-3.4.0/vm_dump.c:1151
ruby(rb_bug_for_fatal_signal+0xfc) [0x5577db3cc60c] ruby-3.4.0/error.c:1066
ruby(sigsegv+0x4d) [0x5577db16358d] ruby-3.4.0/signal.c:926
libc.so.6(0x7f5bacd32520) [0x7f5bacd32520]
ruby(rb_class_superclass+0x32) [0x5577db0a9152] ruby-3.4.0/object.c:2239
ruby(struct_ivar_get+0x2a) [0x5577db194e02] ruby-3.4.0/struct.c:49
ruby(struct_ivar_get) ruby-3.4.0/struct.c:40
ruby(num_members) ruby-3.4.0/struct.c:705
ruby(rb_struct_new+0x56) [0x5577db19a9d6] ruby-3.4.0/struct.c:848
lib/grpc/grpc_c.so(grpc_run_batch_stack_build_result+0xe6) [0x7f5b84bb6b96] /tmp/bundle/ruby/3.4.0+0/bundler/gems/grpc-5ed33ee673e3/src/ruby/ext/grpc/rb_call.c:780
lib/grpc/grpc_c.so(grpc_rb_call_run_batch_try) /tmp/bundle/ruby/3.4.0+0/bundler/gems/grpc-5ed33ee673e3/src/ruby/ext/grpc/rb_call.c:839
ruby(rb_ensure+0x10c) [0x5577db007d3c] ruby-3.4.0/eval.c:1000
/tmp/bundle/ruby/3.4.0+0/bundler/gems/grpc-5ed33ee673e3/src/ruby/lib/grpc/grpc_c.so(grpc_rb_call_run_batch+0xca) [0x7f5b84bb595a] /tmp/bundle/ruby/3.4.0+0/bundler/gems/grpc-5ed33ee673e3/src/ruby/ext/grpc/rb_call.c:893
ruby(vm_call_cfunc_with_frame_+0x117) [0x5577db1f4c77] ruby-3.4.0/vm_insnhelper.c:3524
```

cc @apolcyn @peterzhu2118 @k0kubun

Closes #36125

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36125 from Shopify:fix-ruby-3.4-compat 7a127599c8
PiperOrigin-RevId: 616152904
2024-03-15 09:27:32 -07:00
..
bin [deps] Upgrade protobuf version to v25.0 (#34513) 2023-11-10 00:11:09 -08:00
end2end [ruby] Fix use-after-free for post-fork channel recreation (#35488) 2024-01-17 15:19:45 -08:00
ext/grpc ruby: register grpc_rb_sStatus as a global variable (#36125) 2024-03-15 09:27:32 -07:00
lib [ruby] Make `GRPC::DeadlineExceeded` report properly (#33565) 2024-03-08 17:20:56 -08:00
nativedebug [Release] Bump version to 1.63.0-dev (on master branch) (#35899) 2024-02-13 16:09:36 -08:00
pb [deps] Upgrade protobuf version to v25.0 (#34513) 2023-11-10 00:11:09 -08:00
qps [deps] Upgrade protobuf version to v25.0 (#34513) 2023-11-10 00:11:09 -08:00
spec [ruby] Make `GRPC::DeadlineExceeded` report properly (#33565) 2024-03-08 17:20:56 -08:00
stress auto-fix most of licenses 2017-06-08 11:22:41 +02:00
tools [Release] Bump version to 1.63.0-dev (on master branch) (#35899) 2024-02-13 16:09:36 -08:00
.gitignore Incorporating ruby into the master grpc repository. 2014-12-01 17:45:43 -08:00
.rubocop.yml add end2end tests to formatter and adjust to formatter 2017-03-20 00:07:25 -07:00
.rubocop_todo.yml Update default ruby version to 3.2 on linux/macos ruby builds (#32010) 2023-01-03 13:38:15 -08:00
CHANGELOG.md Corrects the Changelog date 2015-04-14 11:03:37 -07:00
README.md Update Ruby documentation for Gemfile usage (#25705) 2021-04-19 14:31:26 -07:00

README.md

Gem gRPC Ruby

A Ruby implementation of gRPC.

PREREQUISITES

  • Ruby 2.x. The gRPC API uses keyword args.

INSTALLATION

Linux and Mac OS X:

gem install grpc

If using a Gemfile and you wish to pull from a git repository or GitHub, make sure to tell bundler to retrieve submodules:

gem 'grpc', github: 'grpc/grpc', submodules: true

BUILD FROM SOURCE

  • Clone this repository

  • Init submodules

git submodule update --init
  • Install Ruby 2.x. Consider doing this with RVM, it's a nice way of controlling the exact ruby version that's used.
$ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
$
$ # follow the instructions to ensure that your're using the latest stable version of Ruby
$ # and that the rvm command is installed
  • Make sure your run source $HOME/.rvm/scripts/rvm as instructed to complete the set up of RVM

  • Install bundler

$ gem install bundler
  • Finally, build and install the gRPC gem locally.
$ # from this directory
$ bundle install  # creates the ruby bundle, including building the grpc extension
$ rake  # runs the unit tests, see rake -T for other options

DOCUMENTATION

  • rubydoc for the gRPC gem is available online at rubydoc.
  • the gRPC Ruby reference documentation is available online at grpc.io

CONTENTS

Directory structure is the layout for ruby extensions

  • ext: the gRPC ruby extension

  • lib: the entrypoint gRPC ruby library to be used in a 'require' statement

  • spec: Rspec unittests

  • bin: example gRPC clients and servers, e.g,

    stub = Math::Math::Stub.new('my.test.math.server.com:8080', :this_channel_is_insecure)
    req = Math::DivArgs.new(dividend: 7, divisor: 3)
    GRPC.logger.info("div(7/3): req=#{req.inspect}")
    resp = stub.div(req)
    GRPC.logger.info("Answer: #{resp.inspect}")