Bug #18140
closedGC prematurely frees objects from implicit #to_ary conversion, leading to segfault
Description
The following repro crashes in every version of Ruby starting from 2.5.0 and including the latest (3.0.2):
// test_ext.c
#include "ruby.h"
VALUE cFoo;
// Foo
typedef struct {
int dummy;
} Foo;
static void Foo_free(void* _self) {
fprintf(stderr, "Foo_free(%p)\n", _self);
xfree(_self);
}
static rb_data_type_t Foo_type = {
"Foo",
{NULL, Foo_free, NULL },
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE Foo_alloc(VALUE klass) {
Foo* _self = ALLOC(Foo);
fprintf(stderr, "Foo_alloc(%p)\n", _self);
return TypedData_Wrap_Struct(klass, &Foo_type, _self);
}
// Bar
typedef struct {
int dummy;
} Bar;
static void Bar_free(void* _self) {
fprintf(stderr, "Bar_free(%p)\n", _self);
xfree(_self);
}
static rb_data_type_t Bar_type = {
"Bar",
{NULL, Bar_free, NULL },
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
};
static VALUE Bar_alloc(VALUE klass) {
Bar* bar = ALLOC(Bar);
return TypedData_Wrap_Struct(klass, &Bar_type, bar);
}
VALUE Bar_to_ary(VALUE _self) {
fprintf(stderr, "Bar_to_ary() begin\n");
VALUE ary = rb_ary_new2(2);
rb_ary_push(ary, Foo_alloc(cFoo));
rb_ary_push(ary, Foo_alloc(cFoo));
rb_ary_push(ary, Foo_alloc(cFoo));
fprintf(stderr, "Bar_to_ary() end\n");
return ary;
}
void Init_test_ext() {
cFoo = rb_define_class("Foo", rb_cObject);
rb_gc_register_address(&cFoo);
rb_define_alloc_func(cFoo, Foo_alloc);
VALUE bar = rb_define_class("Bar", rb_cObject);
rb_define_alloc_func(bar, Bar_alloc);
rb_define_method(bar, "to_ary", Bar_to_ary, 0);
}
#!/usr/bin/ruby
require 'mkmf'
$objs = ["test_ext.o"]
create_makefile("test_ext")
// test.rb
require "test_ext"
GC.stress = true
arr = [nil]
STDERR.puts("Bar.new")
bar = Bar.new
STDERR.puts("concat")
arr.concat(bar)
STDERR.puts("concat done")
Output is:
Bar.new
concat
Bar_to_ary() begin
Foo_alloc(0x55580d816360)
Foo_alloc(0x55580d993fe0)
Foo_alloc(0x55580d8f58e0)
Bar_to_ary() end
Foo_free(0x55580d8f58e0)
Foo_free(0x55580d993fe0)
Foo_free(0x55580d816360)
<OBJ_INFO:gc_mark_ptr@gc.c:6113> 0x000055580d997e50 [2 M ] T_NONE
test.rb:11: [BUG] try to mark T_NONE object
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0002 p:0081 s:0009 E:002120 EVAL test.rb:11 [FINISH]
c:0001 p:0000 s:0003 E:000ab0 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
test.rb:11:in `<main>'
-- C level backtrace information -------------------------------------------
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_print_backtrace+0x11) [0x55580d294925] vm_dump.c:758
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_vm_bugreport) vm_dump.c:998
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(bug_report_end+0x0) [0x55580d33a3ad] error.c:763
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_bug_without_die) error.c:763
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(die+0x0) [0x55580d09584c] error.c:771
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_bug) error.c:773
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_mark_ptr+0x140) [0x55580d0b6d10] gc.c:6114
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_mark_children+0x88b) [0x55580d0b84eb] gc.c:6147
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_mark_stacked_objects+0x3f) [0x55580d0b9007] gc.c:6467
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_mark_stacked_objects_incremental) gc.c:6501
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_marks_rest) gc.c:7444
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_rest+0xc0) [0x55580d0b9e90] gc.c:8343
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(gc_rest+0x8) [0x55580d0b9f70] gc.c:8215
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(garbage_collect) gc.c:8204
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(newobj_slowpath+0x143) [0x55580d0bd413] gc.c:2257
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(newobj_slowpath_wb_protected) gc.c:2284
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(newobj_of0+0x5) [0x55580d0bd4b5] gc.c:2323
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(newobj_of_cr) gc.c:2340
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_ec_wb_protected_newobj_of) gc.c:2362
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(memcpy+0x0) [0x55580d20705f] string.c:1548
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(ruby_nonempty_memcpy) ./include/ruby/internal/memory.h:269
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(ruby_nonempty_memcpy) ./include/ruby/internal/memory.h:266
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(str_duplicate_setup) string.c:1563
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(ec_str_duplicate) string.c:1595
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_ec_str_resurrect) string.c:1622
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(vm_exec_core+0xdee) [0x55580d28208e] insns.def:366
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_vm_exec+0x17f) [0x55580d2773cf] vm.c:2163
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(rb_ec_exec_node+0xc6) [0x55580d095d96] eval.c:317
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(ruby_run_node+0x49) [0x55580d09a739] eval.c:375
/usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby(main+0x5b) [0x55580d095b4b] error.c:3076
-- Other runtime information -----------------------------------------------
* Loaded script: test.rb
* Loaded features:
0 enumerator.so
1 thread.rb
2 rational.so
3 complex.so
4 ruby2_keywords.rb
5 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so
6 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/trans/transdb.so
7 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/rbconfig.rb
8 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/compatibility.rb
9 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/defaults.rb
10 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/deprecate.rb
11 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/errors.rb
12 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/exceptions.rb
13 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/basic_specification.rb
14 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/stub_specification.rb
15 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/text.rb
16 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/user_interaction.rb
17 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/specification_policy.rb
18 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/util/list.rb
19 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/platform.rb
20 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/version.rb
21 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/requirement.rb
22 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/specification.rb
23 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/util.rb
24 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/dependency.rb
25 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/core_ext/kernel_gem.rb
26 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/monitor.so
27 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/monitor.rb
28 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb
29 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/core_ext/kernel_warn.rb
30 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems.rb
31 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/rubygems/path_support.rb
32 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/version.rb
33 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/core_ext/name_error.rb
34 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/levenshtein.rb
35 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/jaro_winkler.rb
36 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checker.rb
37 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
38 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
39 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/name_error_checkers.rb
40 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/method_name_checker.rb
41 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/key_error_checker.rb
42 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/null_checker.rb
43 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/tree_spell_checker.rb
44 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/spell_checkers/require_path_checker.rb
45 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean/formatters/plain_formatter.rb
46 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/did_you_mean.rb
47 /usr/local/google/home/haberman/code/protobuf/ruby/test_repro/test_ext.so
* Process memory map:
55580d068000-55580d090000 r--p 00000000 fd:01 36594071 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby
55580d090000-55580d347000 r-xp 00028000 fd:01 36594071 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby
55580d347000-55580d452000 r--p 002df000 fd:01 36594071 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby
55580d453000-55580d459000 r--p 003ea000 fd:01 36594071 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby
55580d459000-55580d45a000 rw-p 003f0000 fd:01 36594071 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby
55580d45a000-55580d46b000 rw-p 00000000 00:00 0
55580d60d000-55580d9e5000 rw-p 00000000 00:00 0 [heap]
7fbaca742000-7fbaca904000 r--s 00000000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbaca904000-7fbaccc1c000 r--s 00000000 fd:01 36594071 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/bin/ruby
7fbaccc1c000-7fbaccc1f000 r--p 00000000 fd:01 33948594 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fbaccc1f000-7fbaccc30000 r-xp 00003000 fd:01 33948594 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fbaccc30000-7fbaccc34000 r--p 00014000 fd:01 33948594 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fbaccc34000-7fbaccc35000 r--p 00017000 fd:01 33948594 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fbaccc35000-7fbaccc36000 rw-p 00018000 fd:01 33948594 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fbaccc56000-7fbaccc57000 ---p 00000000 00:00 0
7fbaccc57000-7fbacccf8000 rw-p 00000000 00:00 0
7fbacccf8000-7fbacccf9000 ---p 00000000 00:00 0
7fbacccf9000-7fbaccd9a000 rw-p 00000000 00:00 0
7fbaccd9a000-7fbaccd9b000 ---p 00000000 00:00 0
7fbaccd9b000-7fbacce3c000 rw-p 00000000 00:00 0
7fbacce3c000-7fbacce3d000 ---p 00000000 00:00 0
7fbacce3d000-7fbaccede000 rw-p 00000000 00:00 0
7fbaccede000-7fbaccedf000 ---p 00000000 00:00 0
7fbaccedf000-7fbaccf80000 rw-p 00000000 00:00 0
7fbaccf80000-7fbaccf81000 ---p 00000000 00:00 0
7fbaccf81000-7fbacd022000 rw-p 00000000 00:00 0
7fbacd022000-7fbacd023000 ---p 00000000 00:00 0
7fbacd023000-7fbacd0c4000 rw-p 00000000 00:00 0
7fbacd0c4000-7fbacd0c5000 ---p 00000000 00:00 0
7fbacd0c5000-7fbacd166000 rw-p 00000000 00:00 0
7fbacd166000-7fbacd167000 ---p 00000000 00:00 0
7fbacd167000-7fbacd208000 rw-p 00000000 00:00 0
7fbacd208000-7fbacd209000 ---p 00000000 00:00 0
7fbacd209000-7fbacd2aa000 rw-p 00000000 00:00 0
7fbacd2aa000-7fbacd2ab000 ---p 00000000 00:00 0
7fbacd2ab000-7fbacd34c000 rw-p 00000000 00:00 0
7fbacd34c000-7fbacd34d000 ---p 00000000 00:00 0
7fbacd34d000-7fbacd3ee000 rw-p 00000000 00:00 0
7fbacd3ee000-7fbacd3ef000 ---p 00000000 00:00 0
7fbacd3ef000-7fbacd490000 rw-p 00000000 00:00 0
7fbacd490000-7fbacd491000 ---p 00000000 00:00 0
7fbacd491000-7fbacd532000 rw-p 00000000 00:00 0
7fbacd532000-7fbacd533000 ---p 00000000 00:00 0
7fbacd533000-7fbacd5d4000 rw-p 00000000 00:00 0
7fbacd5d4000-7fbacd5d5000 ---p 00000000 00:00 0
7fbacd5d5000-7fbacd676000 rw-p 00000000 00:00 0
7fbacd676000-7fbacd677000 ---p 00000000 00:00 0
7fbacd677000-7fbacd718000 rw-p 00000000 00:00 0
7fbacd718000-7fbacd719000 ---p 00000000 00:00 0
7fbacd719000-7fbacd7ba000 rw-p 00000000 00:00 0
7fbacd7ba000-7fbacd7bb000 ---p 00000000 00:00 0
7fbacd7bb000-7fbacd85c000 rw-p 00000000 00:00 0
7fbacd85c000-7fbacd85d000 ---p 00000000 00:00 0
7fbacd85d000-7fbacd8fe000 rw-p 00000000 00:00 0
7fbacd8fe000-7fbacd8ff000 ---p 00000000 00:00 0
7fbacd8ff000-7fbacd9a0000 rw-p 00000000 00:00 0
7fbacd9a0000-7fbacd9a1000 ---p 00000000 00:00 0
7fbacd9a1000-7fbacda42000 rw-p 00000000 00:00 0
7fbacda42000-7fbacda43000 ---p 00000000 00:00 0
7fbacda43000-7fbacdae4000 rw-p 00000000 00:00 0
7fbacdae4000-7fbacdae5000 ---p 00000000 00:00 0
7fbacdae5000-7fbacdb86000 rw-p 00000000 00:00 0
7fbacdb86000-7fbacdb87000 ---p 00000000 00:00 0
7fbacdb87000-7fbacdc28000 rw-p 00000000 00:00 0
7fbacdc28000-7fbacdc29000 ---p 00000000 00:00 0
7fbacdc29000-7fbacdcca000 rw-p 00000000 00:00 0
7fbacdcca000-7fbacdccb000 ---p 00000000 00:00 0
7fbacdccb000-7fbacdd6c000 rw-p 00000000 00:00 0
7fbacdd6c000-7fbacdd6d000 ---p 00000000 00:00 0
7fbacdd6d000-7fbacde0e000 rw-p 00000000 00:00 0
7fbacde0e000-7fbacde0f000 ---p 00000000 00:00 0
7fbacde0f000-7fbacdeb0000 rw-p 00000000 00:00 0
7fbacdeb0000-7fbacdeb1000 ---p 00000000 00:00 0
7fbacdeb1000-7fbacdf52000 rw-p 00000000 00:00 0
7fbacdf52000-7fbacdf53000 ---p 00000000 00:00 0
7fbacdf53000-7fbacdff4000 rw-p 00000000 00:00 0
7fbacdff4000-7fbacdff5000 ---p 00000000 00:00 0
7fbacdff5000-7fbad0201000 rw-p 00000000 00:00 0
7fbad0201000-7fbad04e8000 r--p 00000000 fd:01 33030163 /usr/lib/locale/locale-archive
7fbad04e8000-7fbad04ea000 rw-p 00000000 00:00 0
7fbad04ea000-7fbad050f000 r--p 00000000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbad050f000-7fbad065a000 r-xp 00025000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbad065a000-7fbad06a4000 r--p 00170000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbad06a4000-7fbad06a5000 ---p 001ba000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbad06a5000-7fbad06a8000 r--p 001ba000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbad06a8000-7fbad06ab000 rw-p 001bd000 fd:01 33948006 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7fbad06ab000-7fbad06af000 rw-p 00000000 00:00 0
7fbad06af000-7fbad06be000 r--p 00000000 fd:01 33948010 /usr/lib/x86_64-linux-gnu/libm-2.31.so
7fbad06be000-7fbad0758000 r-xp 0000f000 fd:01 33948010 /usr/lib/x86_64-linux-gnu/libm-2.31.so
7fbad0758000-7fbad07f1000 r--p 000a9000 fd:01 33948010 /usr/lib/x86_64-linux-gnu/libm-2.31.so
7fbad07f1000-7fbad07f2000 r--p 00141000 fd:01 33948010 /usr/lib/x86_64-linux-gnu/libm-2.31.so
7fbad07f2000-7fbad07f3000 rw-p 00142000 fd:01 33948010 /usr/lib/x86_64-linux-gnu/libm-2.31.so
7fbad07f3000-7fbad07f5000 rw-p 00000000 00:00 0
7fbad07f5000-7fbad07f7000 r--p 00000000 fd:01 33949537 /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fbad07f7000-7fbad080c000 r-xp 00002000 fd:01 33949537 /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fbad080c000-7fbad0826000 r--p 00017000 fd:01 33949537 /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fbad0826000-7fbad0827000 r--p 00030000 fd:01 33949537 /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fbad0827000-7fbad0828000 rw-p 00031000 fd:01 33949537 /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fbad0828000-7fbad0830000 rw-p 00000000 00:00 0
7fbad0830000-7fbad0831000 r--p 00000000 fd:01 33948008 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7fbad0831000-7fbad0833000 r-xp 00001000 fd:01 33948008 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7fbad0833000-7fbad0834000 r--p 00003000 fd:01 33948008 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7fbad0834000-7fbad0835000 r--p 00003000 fd:01 33948008 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7fbad0835000-7fbad0836000 rw-p 00004000 fd:01 33948008 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7fbad0836000-7fbad0841000 r--p 00000000 fd:01 33948804 /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fbad0841000-7fbad089d000 r-xp 0000b000 fd:01 33948804 /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fbad089d000-7fbad08b4000 r--p 00067000 fd:01 33948804 /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fbad08b4000-7fbad08b5000 ---p 0007e000 fd:01 33948804 /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fbad08b5000-7fbad08b6000 r--p 0007e000 fd:01 33948804 /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fbad08b6000-7fbad08b7000 rw-p 0007f000 fd:01 33948804 /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fbad08b7000-7fbad08ba000 r--p 00000000 fd:01 33948060 /usr/lib/x86_64-linux-gnu/librt-2.31.so
7fbad08ba000-7fbad08be000 r-xp 00003000 fd:01 33948060 /usr/lib/x86_64-linux-gnu/librt-2.31.so
7fbad08be000-7fbad08bf000 r--p 00007000 fd:01 33948060 /usr/lib/x86_64-linux-gnu/librt-2.31.so
7fbad08bf000-7fbad08c0000 ---p 00008000 fd:01 33948060 /usr/lib/x86_64-linux-gnu/librt-2.31.so
7fbad08c0000-7fbad08c1000 r--p 00008000 fd:01 33948060 /usr/lib/x86_64-linux-gnu/librt-2.31.so
7fbad08c1000-7fbad08c2000 rw-p 00009000 fd:01 33948060 /usr/lib/x86_64-linux-gnu/librt-2.31.so
7fbad08c2000-7fbad08c9000 r--p 00000000 fd:01 33948052 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7fbad08c9000-7fbad08d9000 r-xp 00007000 fd:01 33948052 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7fbad08d9000-7fbad08de000 r--p 00017000 fd:01 33948052 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7fbad08de000-7fbad08df000 r--p 0001b000 fd:01 33948052 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7fbad08df000-7fbad08e0000 rw-p 0001c000 fd:01 33948052 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7fbad08e0000-7fbad08e4000 rw-p 00000000 00:00 0
7fbad08e4000-7fbad08e7000 r--p 00000000 fd:01 33949871 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fbad08e7000-7fbad08f8000 r-xp 00003000 fd:01 33949871 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fbad08f8000-7fbad08fe000 r--p 00014000 fd:01 33949871 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fbad08fe000-7fbad08ff000 ---p 0001a000 fd:01 33949871 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fbad08ff000-7fbad0900000 r--p 0001a000 fd:01 33949871 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fbad0900000-7fbad0901000 rw-p 0001b000 fd:01 33949871 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fbad0905000-7fbad0906000 r--p 00000000 fd:01 38420503 /usr/local/google/home/haberman/code/protobuf/ruby/test_repro/test_ext.so
7fbad0906000-7fbad0907000 r-xp 00001000 fd:01 38420503 /usr/local/google/home/haberman/code/protobuf/ruby/test_repro/test_ext.so
7fbad0907000-7fbad0908000 r--p 00002000 fd:01 38420503 /usr/local/google/home/haberman/code/protobuf/ruby/test_repro/test_ext.so
7fbad0908000-7fbad0909000 r--p 00002000 fd:01 38420503 /usr/local/google/home/haberman/code/protobuf/ruby/test_repro/test_ext.so
7fbad0909000-7fbad090a000 rw-p 00003000 fd:01 38420503 /usr/local/google/home/haberman/code/protobuf/ruby/test_repro/test_ext.so
7fbad090a000-7fbad090b000 r--p 00000000 fd:01 36723526 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/monitor.so
7fbad090b000-7fbad090c000 r-xp 00001000 fd:01 36723526 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/monitor.so
7fbad090c000-7fbad090d000 r--p 00002000 fd:01 36723526 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/monitor.so
7fbad090d000-7fbad090e000 r--p 00002000 fd:01 36723526 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/monitor.so
7fbad090e000-7fbad090f000 rw-p 00003000 fd:01 36723526 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/monitor.so
7fbad090f000-7fbad0910000 r--p 00000000 fd:01 36978765 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/trans/transdb.so
7fbad0910000-7fbad0912000 r-xp 00001000 fd:01 36978765 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/trans/transdb.so
7fbad0912000-7fbad0913000 r--p 00003000 fd:01 36978765 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/trans/transdb.so
7fbad0913000-7fbad0914000 r--p 00003000 fd:01 36978765 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/trans/transdb.so
7fbad0914000-7fbad0915000 rw-p 00004000 fd:01 36978765 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/trans/transdb.so
7fbad0915000-7fbad0916000 r--p 00000000 fd:01 36983946 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so
7fbad0916000-7fbad0917000 r-xp 00001000 fd:01 36983946 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so
7fbad0917000-7fbad0918000 r--p 00002000 fd:01 36983946 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so
7fbad0918000-7fbad0919000 r--p 00002000 fd:01 36983946 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so
7fbad0919000-7fbad091a000 rw-p 00003000 fd:01 36983946 /usr/local/google/home/haberman/.rubies/ruby-3.0.2/lib/ruby/3.0.0/x86_64-linux/enc/encdb.so
7fbad091a000-7fbad0921000 r--s 00000000 fd:01 33958468 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7fbad0921000-7fbad0923000 rw-p 00000000 00:00 0
7fbad0923000-7fbad0924000 r--p 00000000 fd:01 33947998 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fbad0924000-7fbad0944000 r-xp 00001000 fd:01 33947998 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fbad0944000-7fbad094c000 r--p 00021000 fd:01 33947998 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fbad094d000-7fbad094e000 r--p 00029000 fd:01 33947998 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fbad094e000-7fbad094f000 rw-p 0002a000 fd:01 33947998 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7fbad094f000-7fbad0950000 rw-p 00000000 00:00 0
7ffd498ac000-7ffd4a0ab000 rw-p 00000000 00:00 0 [stack]
7ffd4a193000-7ffd4a197000 r--p 00000000 00:00 0 [vvar]
7ffd4a197000-7ffd4a199000 r-xp 00000000 00:00 0 [vdso]
Files
Updated by jhaberman (Josh Haberman) about 3 years ago
I should mention that the SEGV goes away if you explicitly convert to array first, instead of letting Array#concat
do it implicitly:
require "test_ext"
GC.stress = true
arr = [nil]
STDERR.puts("Bar.new")
bar = Bar.new
STDERR.puts("concat")
arr.concat(bar.to_ary) # Doesn't crash
STDERR.puts("concat done")
So it seems to be related to the way that Array#concat
is implicitly converting the object to an array with #to_ary
. The implementation of Array#concat
doesn't appear to be properly GC-rooting the temporary array in this case.
Updated by tenderlovemaking (Aaron Patterson) about 3 years ago
I think we need a GC guard in ary_append
. We're calling rb_ary_splice
with the underlying array pointer. The compiler probably optimized away writing y
anywhere in the stack so the GC doesn't see it. Explicitly casting to to_ary
would put the array on the Ruby stack and the GC can see it.
I've attached a patch that fixes the issue for me (also compiling without optimizations fixes it, which definitely makes it seem like a compiler optimization problem).
Updated by jhaberman (Josh Haberman) about 3 years ago
Amazingly quick confirmation, diagnosis, and fix. Thank you!
Updated by stanhu (Stan Hu) about 3 years ago
Thanks for the quick patch, Aaron! Thanks, Josh, for taking the initial repro step and boiling it down even further.
This explains why I didn't see the problem when I compiled Ruby with -O0
.
Updated by nobu (Nobuyoshi Nakada) about 3 years ago
- Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.6: REQUIRED, 2.7: REQUIRED, 3.0: REQUIRED
Updated by tenderlovemaking (Aaron Patterson) about 3 years ago
- Status changed from Open to Closed
Applied in changeset git|cd4f5b13228879d954fa97b6aa479c4a5ef4fb0a.
Guard array when appending
This prevents early collection of the array. The GC doesn't see the
array on the stack when Ruby is compiled with optimizations enabled
[ruby-core:105099] [Bug #18140]
Updated by nagachika (Tomoyuki Chikanaga) about 3 years ago
- Backport changed from 2.6: REQUIRED, 2.7: REQUIRED, 3.0: REQUIRED to 2.6: REQUIRED, 2.7: REQUIRED, 3.0: DONE
ruby_3_0 92846db6861eed324288819157e6c7722fc62fc2 merged revision(s) cd4f5b13228879d954fa97b6aa479c4a5ef4fb0a,8db269edb3550a85dfab9b193ea115ca36912ced,ab63f6d8543903f177c46634f38e5428655f003b.