diff options
author | Aaron Patterson <[email protected]> | 2021-05-24 14:23:45 -0700 |
---|---|---|
committer | Aaron Patterson <[email protected]> | 2021-05-26 14:21:54 -0700 |
commit | 8fdb15fdd3ed2636d28d60153a7520256d72594e (patch) | |
tree | a7e9ea9245d690c953f12c26fe56b20b22d299b7 /gc.c | |
parent | af43198738bf45d55d91d7f48b197f94dc526967 (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
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 43 |
1 files changed, 36 insertions, 7 deletions
@@ -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 |