summaryrefslogtreecommitdiff
path: root/weakmap.c
diff options
context:
space:
mode:
authorLuke Gruber <luke.gruber@shopify.com>2025-12-18 15:42:49 -0500
committerGitHub <noreply@github.com>2025-12-18 15:42:49 -0500
commitaace29d485559e38ca06923a6af335dbb5fb28f1 (patch)
tree0742779ec540b43a16696ca7978a7a27b65f4495 /weakmap.c
parenta7eb1879ad35a0b5d9d32fcdbf2f840bd2c8858c (diff)
Check for NULL fields in TYPEDDATA memsize functions (#15633)
Some TYPEDDATA objects allocate struct fields using the GC right after they get created, and in that case the VM can try to perform a GC and join a barrier if another ractor started one. If we're dumping the heap in another ractor, this acquires a barrier and it will call the `rb_obj_memsize` function on this object. We can't assume these struct fields are non-null. This also goes for C extensions, which may cause problems with heap dumping from a ractor if their memsize functions aren't coded correctly to check for NULL fields. Because dumping the heap from a ractor is likely a rare scenario and it has only recently been introduced, we'll have to see how this works in practice and if it causes bugs.
Diffstat (limited to 'weakmap.c')
-rw-r--r--weakmap.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/weakmap.c b/weakmap.c
index 2ebf7d204f..ecdd219f62 100644
--- a/weakmap.c
+++ b/weakmap.c
@@ -139,9 +139,11 @@ wmap_memsize(const void *ptr)
const struct weakmap *w = ptr;
size_t size = 0;
- size += st_memsize(w->table);
- /* The key and value of the table each take sizeof(VALUE) in size. */
- size += st_table_size(w->table) * (2 * sizeof(VALUE));
+ if (w->table) {
+ size += st_memsize(w->table);
+ /* The key and value of the table each take sizeof(VALUE) in size. */
+ size += st_table_size(w->table) * (2 * sizeof(VALUE));
+ }
return size;
}
@@ -689,9 +691,11 @@ wkmap_memsize(const void *ptr)
const struct weakkeymap *w = ptr;
size_t size = 0;
- size += st_memsize(w->table);
- /* Each key of the table takes sizeof(VALUE) in size. */
- size += st_table_size(w->table) * sizeof(VALUE);
+ if (w->table) {
+ size += st_memsize(w->table);
+ /* Each key of the table takes sizeof(VALUE) in size. */
+ size += st_table_size(w->table) * sizeof(VALUE);
+ }
return size;
}