mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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.
This commit is contained in:
parent
af43198738
commit
8fdb15fdd3
Notes:
git
2021-05-27 06:22:22 +09:00
1 changed files with 36 additions and 7 deletions
43
gc.c
43
gc.c
|
@ -1794,6 +1794,8 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj
|
||||||
|
|
||||||
RVALUE *p = (RVALUE *)obj;
|
RVALUE *p = (RVALUE *)obj;
|
||||||
|
|
||||||
|
asan_unpoison_object(obj, false);
|
||||||
|
|
||||||
asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
|
|
||||||
p->as.free.flags = 0;
|
p->as.free.flags = 0;
|
||||||
|
@ -5863,24 +5865,51 @@ push_mark_stack(mark_stack_t *stack, VALUE data)
|
||||||
{
|
{
|
||||||
VALUE obj = data;
|
VALUE obj = data;
|
||||||
switch (BUILTIN_TYPE(obj)) {
|
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_NIL:
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_MOVED:
|
case T_MOVED:
|
||||||
|
case T_ZOMBIE:
|
||||||
|
case T_UNDEF:
|
||||||
|
case T_MASK:
|
||||||
rb_bug("push_mark_stack() called for broken object");
|
rb_bug("push_mark_stack() called for broken object");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_NODE:
|
case T_NODE:
|
||||||
UNEXPECTED_NODE(push_mark_stack);
|
UNEXPECTED_NODE(push_mark_stack);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack->index == stack->limit) {
|
rb_bug("rb_gc_mark(): unknown data type 0x%x(%p) %s",
|
||||||
push_mark_stack_chunk(stack);
|
BUILTIN_TYPE(obj), (void *)data,
|
||||||
}
|
is_pointer_to_heap(&rb_objspace, (void *)data) ? "corrupted object" : "non object");
|
||||||
stack->chunk->data[stack->index++] = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Reference in a new issue