ruby-changes:55201
From: tenderlove <ko1@a...>
Date: Tue, 2 Apr 2019 08:55:08 +0900 (JST)
Subject: [ruby-changes:55201] tenderlove:r67408 (trunk): Fix ASAN errors when walking the heap
tenderlove 2019-04-02 08:55:02 +0900 (Tue, 02 Apr 2019) New Revision: 67408 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67408 Log: 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 Modified files: trunk/gc.c Index: gc.c =================================================================== --- gc.c (revision 67407) +++ gc.c (revision 67408) @@ -3050,6 +3050,7 @@ rb_objspace_call_finalizer(rb_objspace_t https://github.com/ruby/ruby/blob/trunk/gc.c#L3050 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L3075 } 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L5326 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L5363 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 *objsp https://github.com/ruby/ruby/blob/trunk/gc.c#L5385 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 *objsp https://github.com/ruby/ruby/blob/trunk/gc.c#L5397 has_remembered_old = TRUE; remembered_old_objects++; } + + if (poisoned) { + GC_ASSERT(BUILTIN_TYPE(val) == T_NONE); + poison_object(val); + } } if (!is_incremental_marking(objspace) && -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/