From 1ad6dde9da48149f1998eb5b85916165867c2368 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Mon, 1 Apr 2019 23:55:02 +0000 Subject: Fix ASAN errors when walking the heap verify_internal_consistency_i and gc_verify_heap_page would walk the heap, reading data from each slot, but would not unpoison the object before reading. This commit unpoisons the slot before reading so that we won't get ASAN errors git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- gc.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'gc.c') diff --git a/gc.c b/gc.c index e84cb80b99..65face00b9 100644 --- a/gc.c +++ b/gc.c @@ -3050,6 +3050,7 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace) for (i = 0; i < heap_allocated_pages; i++) { p = heap_pages_sorted[i]->start; pend = p + heap_pages_sorted[i]->total_slots; while (p < pend) { + void *poisoned = poisoned_object_p(p); unpoison_object((VALUE)p, false); switch (BUILTIN_TYPE(p)) { case T_DATA: @@ -3074,7 +3075,10 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace) } break; } - poison_object((VALUE)p); + if (poisoned) { + GC_ASSERT(BUILTIN_TYPE(p) == T_NONE); + poison_object((VALUE)p); + } p++; } } @@ -5322,6 +5326,9 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, v rb_objspace_t *objspace = data->objspace; for (obj = (VALUE)page_start; obj != (VALUE)page_end; obj += stride) { + void *poisoned = poisoned_object_p(obj); + unpoison_object(obj, false); + if (is_live_object(objspace, obj)) { /* count objects */ data->live_object_count++; @@ -5356,6 +5363,10 @@ verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, v data->zombie_object_count++; } } + if (poisoned) { + GC_ASSERT(BUILTIN_TYPE(obj) == T_NONE); + poison_object(obj); + } } return 0; @@ -5374,6 +5385,9 @@ gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj) for (i=0; itotal_slots; i++) { VALUE val = (VALUE)&page->start[i]; + void *poisoned = poisoned_object_p(val); + unpoison_object(val, false); + if (RBASIC(val) == 0) free_objects++; if (BUILTIN_TYPE(val) == T_ZOMBIE) zombie_objects++; if (RVALUE_PAGE_UNCOLLECTIBLE(page, val) && RVALUE_PAGE_WB_UNPROTECTED(page, val)) { @@ -5383,6 +5397,11 @@ gc_verify_heap_page(rb_objspace_t *objspace, struct heap_page *page, VALUE obj) has_remembered_old = TRUE; remembered_old_objects++; } + + if (poisoned) { + GC_ASSERT(BUILTIN_TYPE(val) == T_NONE); + poison_object(val); + } } if (!is_incremental_marking(objspace) && -- cgit v1.2.3