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

ruby-changes:66333

From: Aaron <ko1@a...>
Date: Thu, 27 May 2021 06:22:07 +0900 (JST)
Subject: [ruby-changes:66333] 8fdb15fdd3 (master): Fill out switch statement in push_mark_stack

https://git.ruby-lang.org/ruby.git/commit/?id=8fdb15fdd3

From 8fdb15fdd3ed2636d28d60153a7520256d72594e Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Mon, 24 May 2021 14:23:45 -0700
Subject: Fill out switch statement in push_mark_stack

When objects are popped from the mark stack, we check that the object is
the right type (otherwise an rb_bug happens).  The problem is that when
we pop a bad object from the stack, we have no idea what pushed the bad
object on the stack.

This change makes an error happen when a bad object is pushed on the
mark stack, that way we can track down the source of the bug.
---
 gc.c | 43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/gc.c b/gc.c
index 64b16c9..3844333 100644
--- a/gc.c
+++ b/gc.c
@@ -1794,6 +1794,8 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj https://github.com/ruby/ruby/blob/trunk/gc.c#L1794
 
     RVALUE *p = (RVALUE *)obj;
 
+    asan_unpoison_object(obj, false);
+
     asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
 
     p->as.free.flags = 0;
@@ -5863,24 +5865,51 @@ push_mark_stack(mark_stack_t *stack, VALUE data) https://github.com/ruby/ruby/blob/trunk/gc.c#L5865
 {
     VALUE obj = data;
     switch (BUILTIN_TYPE(obj)) {
+      case T_OBJECT:
+      case T_CLASS:
+      case T_MODULE:
+      case T_FLOAT:
+      case T_STRING:
+      case T_REGEXP:
+      case T_ARRAY:
+      case T_HASH:
+      case T_STRUCT:
+      case T_BIGNUM:
+      case T_FILE:
+      case T_DATA:
+      case T_MATCH:
+      case T_COMPLEX:
+      case T_RATIONAL:
+      case T_TRUE:
+      case T_FALSE:
+      case T_SYMBOL:
+      case T_PAYLOAD:
+      case T_IMEMO:
+      case T_ICLASS:
+        if (stack->index == stack->limit) {
+            push_mark_stack_chunk(stack);
+        }
+        stack->chunk->data[stack->index++] = data;
+        return;
+
+      case T_NONE:
       case T_NIL:
       case T_FIXNUM:
       case T_MOVED:
+      case T_ZOMBIE:
+      case T_UNDEF:
+      case T_MASK:
 	rb_bug("push_mark_stack() called for broken object");
 	break;
 
       case T_NODE:
 	UNEXPECTED_NODE(push_mark_stack);
         break;
-
-      default:
-        break;
     }
 
-    if (stack->index == stack->limit) {
-        push_mark_stack_chunk(stack);
-    }
-    stack->chunk->data[stack->index++] = data;
+    rb_bug("rb_gc_mark(): unknown data type 0x%x(%p) %s",
+            BUILTIN_TYPE(obj), (void *)data,
+            is_pointer_to_heap(&rb_objspace, (void *)data) ? "corrupted object" : "non object");
 }
 
 static int
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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