aboutsummaryrefslogtreecommitdiffstats
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
parentf0f6615a25eb87e5e9954b7fec85c71f05100b7d (diff)
downloadruby-1ad6dde9da48149f1998eb5b85916165867c2368.tar.gz
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
-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) &&