diff options
author | Peter Zhu <[email protected]> | 2024-12-16 11:41:41 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2024-12-16 12:24:24 -0500 |
commit | 516a6cd1ad620b880651c1333bd856a9d7dec3c4 (patch) | |
tree | c27c7b4f538b0a751f47498ad380c16c2eaec1f7 /ext/objspace | |
parent | 960f971ac86e0d171fbc3df12bda8c6c81d3ae29 (diff) |
Check whether object is valid in allocation_info_tracer_compact
When reference updating ObjectSpace.trace_object_allocations, we need to
check whether the object is valid or not because it does not mark the
object so the object may be dead. This can cause a segmentation fault
if the object is on a free heap page.
For example, the following script crashes:
require "objspace"
objs = []
ObjectSpace.trace_object_allocations do
1_000_000.times do
objs << Object.new
end
end
objs = nil
# Free pages that the objs were on
GC.start
# Run compaction and check that it doesn't crash
GC.compact
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/12360
Diffstat (limited to 'ext/objspace')
-rw-r--r-- | ext/objspace/object_tracing.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/ext/objspace/object_tracing.c b/ext/objspace/object_tracing.c index 8ea35ef7b7..a52dff736e 100644 --- a/ext/objspace/object_tracing.c +++ b/ext/objspace/object_tracing.c @@ -194,6 +194,10 @@ allocation_info_tracer_compact_update_object_table_i(st_data_t key, st_data_t va { st_table *table = (st_table *)data; + if (!rb_gc_pointer_to_heap_p(key)) { + return ST_DELETE; + } + if (key != rb_gc_location(key)) { DURING_GC_COULD_MALLOC_REGION_START(); { |