This is due to inspect of symbol inside the array.
Somehow the rb_id2str() call in sym_inspect is returning zero.
I'm not sure how that's happening, yet. It seems like the global
symbol table is missing entries somehow, and I fail to see how struct
handles ? methods differently. And I'm too sleepy to dig deeper.
#5 0x00007effeefc904f in rb_str_symname_p (sym=0) at string.c:7817
#6 0x00007effeefc92c6 in sym_inspect (self=5303308) at string.c:7874
#7 0x00007effef00de45 in call_cfunc_0 (func=0x7effeefc9292 <sym_inspect>,
recv=5303308, argc=0, argv=0x0) at vm_insnhelper.c:1336
Work-in-progress patch to clarify the backtrace and reproduce the issue
on 2.0.0:
--- a/string.c
+++ b/string.c
@@ -7861,12 +7861,13 @@ rb_id_quote_unprintable(ID id)
*/
static VALUE
-sym_inspect(VALUE sym)
+sym_inspect(VALUE self)
{
VALUE str;
const char *ptr;
+ VALUE sym;
long len;
- ID id = SYM2ID(sym);
+ ID id = SYM2ID(self);
char *dest;
sym = rb_id2str(id);
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -281,4 +281,9 @@ class TestStruct < Test::Unit::TestCase
o = klass.new(1, 2, 3, 4, 5, 6)
assert_equal({a:1, b:2, c:3, d:4, e:5, f:6}, o.to_h)
end
+
+ def test_struct_question_mark
+ klass = Struct.new(:a?)
+ assert_equal [:a?], klass.new.methods.inspect, "should not segfault"
+ end
end
Oddly: klass.new.methods[0].inspect # does not segfault.
So recursive inspect seems to have something to do with it.