https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112013-12-14T16:53:19ZRuby Issue Tracking SystemBackport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=436702013-12-14T16:53:19Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>Odd, doesn't happen with trunk, but I can reproduce it with 2.0.0-p353<br>
on x86_64-linux. Will try to investigate before falling asleep.</p> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=436732013-12-14T17:53:17Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>This is due to inspect of symbol inside the array.</p>
<p>Somehow the rb_id2str() call in sym_inspect is returning zero.<br>
I'm not sure how that's happening, yet. It seems like the global<br>
symbol table is missing entries somehow, and I fail to see how struct<br>
handles ? methods differently. And I'm too sleepy to dig deeper.</p>
<p>#5 0x00007effeefc904f in rb_str_symname_p (sym=0) at string.c:7817<br>
<a class="issue tracker-1 status-5 priority-4 priority-default closed behind-schedule" title="Bug: sprintf() of %f on Windows(MSVCRT) (Closed)" href="https://bugs.ruby-lang.org/issues/6">#6</a> 0x00007effeefc92c6 in sym_inspect (self=5303308) at string.c:7874<br>
#7 0x00007effef00de45 in call_cfunc_0 (func=0x7effeefc9292 <sym_inspect>,<br>
recv=5303308, argc=0, argv=0x0) at vm_insnhelper.c:1336</p>
<p>Work-in-progress patch to clarify the backtrace and reproduce the issue<br>
on 2.0.0:</p>
<p>--- a/string.c<br>
+++ b/string.c<br>
@@ -7861,12 +7861,13 @@ rb_id_quote_unprintable(ID id)<br>
*/</p>
<p>static VALUE<br>
-sym_inspect(VALUE sym)<br>
+sym_inspect(VALUE self)<br>
{<br>
VALUE str;<br>
const char *ptr;</p>
<ul>
<li>VALUE sym;<br>
long len;</li>
</ul>
<ul>
<li>ID id = SYM2ID(sym);</li>
</ul>
<ul>
<li>
<p>ID id = SYM2ID(self);<br>
char *dest;</p>
<p>sym = rb_id2str(id);<br>
--- a/test/ruby/test_struct.rb<br>
+++ b/test/ruby/test_struct.rb<br>
@@ -281,4 +281,9 @@ class TestStruct < Test::Unit::TestCase<br>
o = klass.new(1, 2, 3, 4, 5, 6)<br>
assert_equal({a:1, b:2, c:3, d:4, e:5, f:6}, o.to_h)<br>
end</p>
</li>
<li>
<li>
<p>def test_struct_question_mark</p>
</li>
<li>
<p>klass = Struct.new(:a?)</p>
</li>
<li>
<p>assert_equal [:a?], klass.new.methods.inspect, "should not segfault"</p>
</li>
<li>
<p>end<br>
end</p>
</li>
</ul>
<p>Oddly: klass.new.methods[0].inspect # does not segfault.<br>
So recursive inspect seems to have something to do with it.</p> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=436762013-12-14T18:54:27Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Backport</i></li><li><strong>Project</strong> changed from <i>Ruby master</i> to <i>Backport200</i></li><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>nagachika (Tomoyuki Chikanaga)</i></li></ul> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=450752014-02-10T16:34:22Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>ruby -v</strong> set to <i>2.0.0p353</i></li></ul><p><a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: SEGFAULT caused by `p Struct.new(:q?).instance_methods` (Closed)" href="https://bugs.ruby-lang.org/issues/8756">#8756</a> seems related with this issue.<br>
I'll backport them and add testcase test_struct_question_mark.<br>
Eric thank you for your report. Have a good sleep.</p> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=450852014-02-11T14:55:11Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>Applied in changeset r44911.</p>
<hr>
<p>merge revision(s) r42479,r42490,r42509,r43083,r43084,r43085: [Backport <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: SEGFAULT caused by `p Struct.new(:q?).instance_methods` (Closed)" href="https://bugs.ruby-lang.org/issues/8756">#8756</a>] [Backport <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Struct methods, segmentation fault (Closed)" href="https://bugs.ruby-lang.org/issues/9248">#9248</a>]</p>
<pre><code>* parse.y (rb_enc_symname_type): allow ID_ATTRSET for ID_INSTANCE,
ID_GLOBAL, ID_CLASS, ID_JUNK too. [Bug #8756]
* parse.y (rb_id_attrset): fix inconsistency with literals, allow
ID_ATTRSET and return it itself, but ID_JUNK cannot make ID_ATTRSET.
and raise a NameError instead of rb_bug() for invalid argument.
* parse.y (rb_id_attrset, intern_str): allow junk attrset ID for
Struct.
* parse.y (rb_id_attrset): check if the argument is valid type as an
attribute.
* parse.y (rb_id_attrset): allow other than ID_ATTRSET.
* parse.y (intern_str): ditto. try stem ID for ID_INSTANCE,
ID_GLOBAL, ID_CLASS, ID_JUNK too. [Bug #8756]
</code></pre> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=450962014-02-12T14:48:52ZEregon (Benoit Daloze)
<ul></ul><p>This still seems problematic:</p>
<pre><code>c = Struct.new(:a?)
o = c.new(42)
o.send("a?=", 3) rescue p $! # => #<NoMethodError: undefined method `a?=' for #<struct :a?=42>>
p o.a?
p o.methods # removing the "p" here would produce a NoMethodError below, somehow this "fixes" everything
o.send("a?=", 3)
p o.a?
</code></pre>
<p>IMHO, adding methods not callable by default because they do not respect the symbol syntax is bad. I would much prefer just to forbid attributes with a final question mark in Struct (or make them behave as the attribute without the "?" and just an extra "#{attr}?" predicate).</p> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=451062014-02-13T07:14:15Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Please backport r44926 too.</p> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=451102014-02-13T16:01:43Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Status</strong> changed from <i>Closed</i> to <i>Assigned</i></li></ul> Backport200 - Backport #9248: Struct methods, segmentation faulthttps://bugs.ruby-lang.org/issues/9248?journal_id=451782014-02-15T14:53:13Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>Applied in changeset r44975.</p>
<hr>
<p>merge revision(s) r44926: [Backport <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: SEGFAULT caused by `p Struct.new(:q?).instance_methods` (Closed)" href="https://bugs.ruby-lang.org/issues/8756">#8756</a>] [Backport <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Struct methods, segmentation fault (Closed)" href="https://bugs.ruby-lang.org/issues/9248">#9248</a>]</p>
<pre><code>* parse.y (IDSET_ATTRSET_FOR_INTERN): fix off-by-one bug.
* parse.y (rb_enc_symname_type): junk ID succeeded by '=' is also
attrset ID. <a href="/issues/8756">[ruby-core:60668]</a> [Bug #8756]
</code></pre>