summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2021-05-24 14:23:45 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2021-05-26 14:21:54 -0700
commit8fdb15fdd3ed2636d28d60153a7520256d72594e (patch)
treea7e9ea9245d690c953f12c26fe56b20b22d299b7
parentaf43198738bf45d55d91d7f48b197f94dc526967 (diff)
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.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4531
-rw-r--r--gc.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/gc.c b/gc.c
index 64b16c92c0..3844333a90 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
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)
{
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