diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index bee8ac288f71..bc318366ad22 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -403,6 +403,9 @@ void ObjectCache_Add(const void *key, VALUE val) { #if USE_SECONDARY_MAP rb_mutex_unlock(secondary_map_mutex); #endif + if (ObjectCache_Get(key) != val) { + rb_bug("ObjectCache_Get(key) != val"); + } PBRUBY_ASSERT(ObjectCache_Get(key) == val); } diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index c6af98fa4727..a4e31d157dd6 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -110,8 +110,12 @@ extern VALUE cTypeError; do { \ } while (false && (expr)) #else +#ifdef RUBY_ASSERT +#define PBRUBY_ASSERT RUBY_ASSERT +#else #define PBRUBY_ASSERT(expr) assert(expr) -#endif +#endif // RUBY_ASSERT +#endif // NDEBUG #define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y)) diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c index 700ca16f38a6..2be23f4242f3 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.c +++ b/ruby/ext/google/protobuf_c/repeated_field.c @@ -432,7 +432,7 @@ static VALUE RepeatedField_dup(VALUE _self) { */ VALUE RepeatedField_to_ary(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - int size = upb_Array_Size(self->array); + int size = self->array ? upb_Array_Size(self->array) : 0; VALUE ary = rb_ary_new2(size); int i; diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index 7351b9cd33e1..22ceab71f190 100755 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -467,6 +467,19 @@ def test_map_wrappers_with_no_value run_asserts.call(m4) end + def test_gc_stress + GC.stress = true + o = Outer.new + o.items[0] = Inner.new + raw = Outer.encode(o) + + 10.times do + assert_equal o, Outer.decode(raw) + end + ensure + GC.stress = false + end + def test_concurrent_decoding o = Outer.new o.items[0] = Inner.new