From e74aa875461e1981ce40fba55a4819c29c998f0a Mon Sep 17 00:00:00 2001 From: cfis Date: Fri, 13 Mar 2026 18:27:01 -0700 Subject: [PATCH 1/2] rb_gc_register_address() can trigger GC, so Anchor must register its VALUE slot before storing a heap object in it. Use RB_GC_GUARD(value) to keep the VALUE alive through the end of the method. --- rice/detail/Anchor.ipp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rice/detail/Anchor.ipp b/rice/detail/Anchor.ipp index 05543136..ddeee59b 100644 --- a/rice/detail/Anchor.ipp +++ b/rice/detail/Anchor.ipp @@ -2,14 +2,20 @@ namespace Rice { namespace detail { - inline Anchor::Anchor(VALUE value) : value_(value) + inline Anchor::Anchor(VALUE value) { + // rb_gc_register_address() can trigger GC, so we must register the + // empty this->value_ slot before storing a heap VALUE in it. + // RB_GC_GUARD(value) keeps the ctor argument alive through the end of + // this method until the registered slot has been updated. if (!RB_SPECIAL_CONST_P(value)) { Anchor::registerExitHandler(); detail::protect(rb_gc_register_address, &this->value_); this->registered_ = true; } + this->value_ = value; + RB_GC_GUARD(value); } inline Anchor::~Anchor() From 85f6fbb36899218afa67254d6f96c71cf793ce51 Mon Sep 17 00:00:00 2001 From: cfis Date: Fri, 13 Mar 2026 21:32:37 -0700 Subject: [PATCH 2/2] Update includes. --- include/rice/rice.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/rice/rice.hpp b/include/rice/rice.hpp index 39a2f031..97bb6fc7 100644 --- a/include/rice/rice.hpp +++ b/include/rice/rice.hpp @@ -1667,14 +1667,20 @@ namespace Rice { namespace detail { - inline Anchor::Anchor(VALUE value) : value_(value) + inline Anchor::Anchor(VALUE value) { + // rb_gc_register_address() can trigger GC, so we must register the + // empty this->value_ slot before storing a heap VALUE in it. + // RB_GC_GUARD(value) keeps the ctor argument alive through the end of + // this method until the registered slot has been updated. if (!RB_SPECIAL_CONST_P(value)) { Anchor::registerExitHandler(); detail::protect(rb_gc_register_address, &this->value_); this->registered_ = true; } + this->value_ = value; + RB_GC_GUARD(value); } inline Anchor::~Anchor()