[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]