From 9a80258b23c76a40070668dbebab8dd6f0361b92 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 15 Oct 2025 19:30:31 -0400 Subject: Fix crash when freeing namespaces remove_class_from_subclasses calls st_insert, which mallocs. Malloc is not allowed in GC. This commit replaces the st_insert with an st_update since we know that ns_id exists in the st_table. The following script reproduces the crash: require "tempfile" Tempfile.create do |file| ns = Namespace.new ns.require(file) end --- class.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'class.c') diff --git a/class.c b/class.c index 84c8668b6b..469cc5e54f 100644 --- a/class.c +++ b/class.c @@ -496,6 +496,13 @@ class_get_subclasses_for_ns(struct st_table *tbl, VALUE ns_id) return NULL; } +static int +remove_class_from_subclasses_replace_first_entry(st_data_t *key, st_data_t *value, st_data_t arg, int existing) +{ + *value = arg; + return ST_CONTINUE; +} + static void remove_class_from_subclasses(struct st_table *tbl, VALUE ns_id, VALUE klass) { @@ -516,7 +523,7 @@ remove_class_from_subclasses(struct st_table *tbl, VALUE ns_id, VALUE klass) if (first_entry) { if (next) { - st_insert(tbl, ns_id, (st_data_t)next); + st_update(tbl, ns_id, remove_class_from_subclasses_replace_first_entry, (st_data_t)next); } else { // no subclass entries in this ns -- cgit v1.2.3