Skip to content

Commit 1f0d41a

Browse files
peterzhu2118matzbot
authored andcommitted
[ruby/date] Call rb_gc_register_mark_object after object allocation
It's possible that both half_days_in_day and day_in_nanoseconds are Ruby objects, which means that creating day_in_nanoseconds may trigger GC. Since half_days_in_day is not registered as a mark object until after day_in_nanoseconds is allocated, the GC may reclaim half_days_in_day. We can see this crash: ruby(rb_print_backtrace+0xb) [0x63a373c0] vm_dump.c:1105 ruby(rb_vm_bugreport) vm_dump.c:1450 ruby(rb_assert_failure_detail+0xdb) [0x6371d3a2] error.c:1216 ruby(RB_FL_TEST_RAW+0x0) [0x6371d3d5] error.c:1192 ruby(rb_assert_failure) (null):0 ruby(rb_gc_impl_writebarrier+0xb4) [0x636f01e4] gc/default/default.c:6103 ruby(pin_array_list_append+0x72) [0x638f9787] include/ruby/internal/gc.h:788 ruby(rb_vm_register_global_object) vm.c:4713 ruby(rb_gc_register_mark_object+0x3a) [0x6374144a] gc.c:3449 .ext/i686-linux-gnu/date_core.so(Init_date_core+0x204) [0xdbec86c4] ext/date/date_core.c:9511 .ext/i686-linux-gnu/date_core.so(Init_date_core) (null):0 ruby(dln_load_and_init+0x71) [0x6392c541] dln.c:521 ruby(dln_load_feature+0xd2) [0x6392c7d2] dln.c:566 ruby(load_ext+0xc3) [0x637931b3] load.c:1210 ruby(rb_vm_pop_frame+0x0) [0x638f80cd] vm.c:3120 ruby(rb_vm_call_cfunc_in_box) vm.c:3122 ruby(rb_long2num_inline+0x0) [0x637956f8] load.c:1353 ruby(require_internal) load.c:1354 ruby(rb_require_string_internal+0x60) [0x63795fa1] load.c:1457 ruby(rb_require_string) load.c:1443 ruby/date@cbec5948e0
1 parent 8d3da81 commit 1f0d41a

File tree

1 file changed

+1
-2
lines changed

1 file changed

+1
-2
lines changed

ext/date/date_core.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9496,6 +9496,7 @@ Init_date_core(void)
94969496
sym_zone = ID2SYM(rb_intern_const("zone"));
94979497

94989498
half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
9499+
rb_gc_register_mark_object(half_days_in_day);
94999500

95009501
#if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
95019502
day_in_nanoseconds = LONG2NUM((long)DAY_IN_SECONDS *
@@ -9507,8 +9508,6 @@ Init_date_core(void)
95079508
day_in_nanoseconds = f_mul(INT2FIX(DAY_IN_SECONDS),
95089509
INT2FIX(SECOND_IN_NANOSECONDS));
95099510
#endif
9510-
9511-
rb_gc_register_mark_object(half_days_in_day);
95129511
rb_gc_register_mark_object(day_in_nanoseconds);
95139512

95149513
positive_inf = +INFINITY;

0 commit comments

Comments
 (0)