Fix ObjectSpace.dump with super() callinfo

super() uses 0 as mid for its callinfo, so we need to check for that to
avoid a segfault when using dump_all.
This commit is contained in:
John Hawthorn 2023-10-11 11:09:04 -07:00
parent 9859dbc7fd
commit 635b92099e
2 changed files with 28 additions and 3 deletions

View File

@ -379,6 +379,7 @@ dump_object(VALUE obj, struct dump_config *dc)
rb_io_t *fptr;
ID flags[RB_OBJ_GC_FLAGS_MAX];
size_t n, i;
ID mid;
if (SPECIAL_CONST_P(obj)) {
dump_append_special_const(dc, obj);
@ -433,9 +434,12 @@ dump_object(VALUE obj, struct dump_config *dc)
switch (imemo_type(obj)) {
case imemo_callinfo:
dump_append(dc, ", \"mid\":\"");
dump_append(dc, RSTRING_PTR(rb_id2str(vm_ci_mid((const struct rb_callinfo *)obj))));
dump_append(dc, "\"");
mid = vm_ci_mid((const struct rb_callinfo *)obj);
if (mid != 0) {
dump_append(dc, ", \"mid\":\"");
dump_append(dc, rb_id2name(mid));
dump_append(dc, "\"");
}
break;
default:

View File

@ -562,6 +562,27 @@ class TestObjSpace < Test::Unit::TestCase
end
end
def test_dump_callinfo_includes_mid
assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error|
begin;
class Foo
def foo
super(bar: 123) # should not crash on 0 mid
end
def bar
baz(bar: 123) # mid: baz
end
end
ObjectSpace.dump_all(output: $stdout)
end;
assert_empty error
assert(output.count > 1)
assert_equal 1, output.count { |l| l.include?('"mid":"baz"') }
end
end
def test_dump_string_coderange
assert_includes ObjectSpace.dump("TEST STRING"), '"coderange":"7bit"'
unknown = "TEST STRING".dup.force_encoding(Encoding::BINARY)