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
This commit is contained in:
tenderlove 2019-04-01 23:55:02 +00:00
Родитель f0f6615a25
Коммит 1ad6dde9da
1 изменённых файлов: 20 добавлений и 1 удалений

21
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; i<page->total_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) &&