summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-01 23:55:02 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-01 23:55:02 +0000
commit1ad6dde9da48149f1998eb5b85916165867c2368 (patch)
tree1d2b8d2141b8473b1b787613862052feff747a1d /gc.c
parentf0f6615a25eb87e5e9954b7fec85c71f05100b7d (diff)
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
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c21
1 files changed, 20 insertions, 1 deletions
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; 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) &&