https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112016-10-12T04:50:40ZRuby Issue Tracking SystemRuby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=608652016-10-12T04:50:40Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>ko1 (Koichi Sasada)</i></li></ul><p>I can reproduce this. Seems like a infinite loop inside of<code>rb_callable_method_entry_without_refinements</code>. I think this is a showstopper bug.</p>
<pre><code>zsh % lldb ./miniruby target.rb
(lldb) target create "./miniruby"
Current executable set to './miniruby' (x86_64).
(lldb) settings set -- target.run-args "target.rb"
(lldb) run
Process 23728 launched: './miniruby' (x86_64)
Process 23728 stopped
* thread #1: tid = 0xea3fd, 0x00000001001f2535 miniruby`rb_callable_method_entry_without_refinements + 24 at vm_method.c:848, stop reason = signal SIGSTOP
frame #0: 0x00000001001f2535 miniruby`rb_callable_method_entry_without_refinements + 24 at vm_method.c:848
845 const rb_method_entry_t *me = method_entry_get(klass, id, defined_class_ptr);
846
847 if (me) {
-> 848 if (me->def->type == VM_METHOD_TYPE_REFINED) {
849 if (with_refinement) {
850 const rb_cref_t *cref = rb_vm_cref();
851 VALUE refinements = cref ? CREF_REFINEMENTS(cref) : Qnil;
(lldb) bt
* thread #1: tid = 0xea3fd, 0x00000001001f2535 miniruby`rb_callable_method_entry_without_refinements + 24 at vm_method.c:848, stop reason = signal SIGSTOP
* frame #0: 0x00000001001f2535 miniruby`rb_callable_method_entry_without_refinements + 24 at vm_method.c:848
frame #1: 0x00000001001f251d miniruby`rb_callable_method_entry_without_refinements(klass=<unavailable>, id=26065) + 13
frame #2: 0x000000010011d820 miniruby`mnew_internal(me=0x000000010185ec40, klass=4320521560, obj=4320521600, id=26065, mclass=4320688000, scope=0, error=1) + 96 at proc.c:1375
frame #3: 0x00000001001210f3 miniruby`rb_obj_method [inlined] mnew_from_me(scope=<unavailable>, mclass=<unavailable>, id=<unavailable>, obj=<unavailable>, klass=<unavailable>, me=<unavailable>) + 26 at proc.c:1403
frame #4: 0x00000001001210d9 miniruby`rb_obj_method + 24
frame #5: 0x00000001001210c1 miniruby`rb_obj_method + 84
frame #6: 0x000000010012106d miniruby`rb_obj_method(obj=4320521600, vid=<unavailable>) + 13
frame #7: 0x00000001001f0e56 miniruby`vm_call_cfunc + 184 at vm_insnhelper.c:1752
frame #8: 0x00000001001f0d9e miniruby`vm_call_cfunc(th=0x0000000100604310, reg_cfp=0x00000001007fffa0, calling=<unavailable>, ci=<unavailable>, cc=<unavailable>) + 46
frame #9: 0x00000001001ff3fe miniruby`vm_call_method_each_type(th=0x0000000100604310, cfp=0x00000001007fffa0, calling=0x00007fff5fbfd900, ci=<unavailable>, cc=<unavailable>) + 142 at vm_insnhelper.c:2138
frame #10: 0x00000001001ff95b miniruby`vm_call_method(th=0x0000000100604310, cfp=0x00000001007fffa0, calling=<unavailable>, ci=<unavailable>, cc=<unavailable>) + 235 at vm_insnhelper.c:2288
frame #11: 0x00000001001f8639 miniruby`vm_exec_core(th=0x0000000100604310, initial=<unavailable>) + 6217 at insns.def:1066
frame #12: 0x00000001001fdda3 miniruby`vm_exec(th=0x0000000100604310) + 131 at vm.c:1711
frame #13: 0x0000000100082bc0 miniruby`ruby_exec_internal(n=0x000000010185f9d8) + 176 at eval.c:244
frame #14: 0x000000010008686f miniruby`ruby_run_node [inlined] ruby_exec_node(n=<unavailable>) + 47 at eval.c:308
frame #15: 0x000000010008685b miniruby`ruby_run_node(n=<unavailable>) + 27
frame #16: 0x000000010021788e miniruby`main(argc=<unavailable>, argv=<unavailable>) + 78 at main.c:36
frame #17: 0x00007fff8dc4f5ad libdyld.dylib`start + 1
frame #18: 0x00007fff8dc4f5ad libdyld.dylib`start + 1
(lldb)
</code></pre> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=608672016-10-12T09:24:36Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Backport</strong> changed from <i>2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN</i> to <i>2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED</i></li></ul> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=608692016-10-12T14:22:09Zfloehopper (James Mead)james@floehopper.org
<ul></ul><p>In case it helps, it seems as if Ruby v2.3 is "more" broken than earlier versions. If I remove the <code>Bar.method(:foo)</code> lookup <em>before</em> the <code>Baz</code> module is prepended, the final lookup still hangs in Ruby v2.3, but not in v2.2. See below:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">Foo</span>
<span class="kp">private</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="s2">"foo"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Bar</span>
<span class="kp">extend</span> <span class="no">Foo</span>
<span class="k">class</span> <span class="o"><<</span> <span class="nb">self</span>
<span class="kp">public</span> <span class="ss">:foo</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Baz</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Bar</span>
<span class="k">class</span> <span class="o"><<</span> <span class="nb">self</span>
<span class="n">prepend</span> <span class="no">Baz</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Bar</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">)</span> <span class="c1"># => hangs in Ruby v2.3.1, but not v2.2.5</span>
</code></pre> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=610542016-10-24T17:24:02Zchrisroos (Chris Roos)
<ul></ul><p>I'm not sure whether this is useful information but calling <code>#instance_method</code> on <code>Bar</code>'s metaclass also causes Ruby to hang. Using James's most recent code snippet, the following code seems to cause the same problem as <code>Bar.method(:foo)</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">metaclass</span> <span class="o">=</span> <span class="p">(</span><span class="k">class</span> <span class="o"><<</span> <span class="no">Bar</span><span class="p">;</span> <span class="nb">self</span><span class="p">;</span> <span class="k">end</span><span class="p">)</span>
<span class="nb">p</span> <span class="n">metaclass</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">)</span> <span class="c1"># => hangs in Ruby v2.3.1, but not v2.2.5</span>
</code></pre> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=610622016-10-25T03:54:14Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>Applied in changeset r56489.</p>
<hr>
<p>proc.c: follow the original class</p>
<ul>
<li>proc.c (mnew_internal): follow the original class, not to loop<br>
the prepended module. <a href="/issues/12832">[ruby-core:77591]</a> [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Calling Object#method hangs for private method defined on module then made public once it's been ... (Closed)" href="https://bugs.ruby-lang.org/issues/12832">#12832</a>]</li>
</ul> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=611622016-11-01T09:34:16Zfloehopper (James Mead)james@floehopper.org
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/4">@nobu (Nobuyoshi Nakada)</a>: Thank you for fixing this. Is it expected that a bug like this would cause the interpreter not to accept interrupt signals?</p> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=611632016-11-01T11:45:56Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>It's not expected but a bug is always what causes unexpected behavior.</p> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=611662016-11-01T12:33:31Zfloehopper (James Mead)james@floehopper.org
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/4">@nobu (Nobuyoshi Nakada)</a>: Is it possible there is a separate problem with the code such that interrupt signals are incorrectly being ignored...?</p> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=611702016-11-01T20:10:48Zkernigh (George Koehler)xkernigh@netscape.net
<ul></ul><p>Ruby defers signals. At safe moments, Ruby checks if a signal arrived, then handles it. If Ruby is stuck in an infinite loop (because of a bug like this one), then Ruby would never check if a signal arrived, so the signal would be ignored. After fixing the bug, signals should work again. Ruby's deferred signals seem like Perl's, see <a href="http://perldoc.perl.org/perlipc.html#Deferred-Signals-(Safe-Signals)" class="external">http://perldoc.perl.org/perlipc.html#Deferred-Signals-(Safe-Signals)</a></p> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=611712016-11-01T20:29:33Zfloehopper (James Mead)james@floehopper.org
<ul></ul><p>@George: Thanks for explaining. Makes sense.</p> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=614432016-11-11T16:02:50Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Backport</strong> changed from <i>2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED</i> to <i>2.1: REQUIRED, 2.2: REQUIRED, 2.3: DONE</i></li></ul><p>ruby_2_3 r56720 merged revision(s) 56489.</p> Ruby master - Bug #12832: Calling Object#method hangs for private method defined on module then made public once it's been used to extend classhttps://bugs.ruby-lang.org/issues/12832?journal_id=614552016-11-11T22:52:18Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<ul><li><strong>Backport</strong> changed from <i>2.1: REQUIRED, 2.2: REQUIRED, 2.3: DONE</i> to <i>2.1: REQUIRED, 2.2: DONE, 2.3: DONE</i></li></ul><p>ruby_2_2 r56731 merged revision(s) 56489.</p>