зеркало из https://github.com/github/ruby.git
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:
Родитель
f0f6615a25
Коммит
1ad6dde9da
21
gc.c
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) &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче