https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112016-07-10T00:49:54ZRuby Issue Tracking SystemRuby master - Bug #12576: SEGV when interrupting tail recursionhttps://bugs.ruby-lang.org/issues/12576?journal_id=595652016-07-10T00:49:54Zshugo (Shugo Maeda)
<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>SEGV occurs as follows:</p>
<ol>
<li>eval pushes a control frame.</li>
<li>foo is called repeatedly without a new control frame.</li>
<li>Interrupted by a signal, and the exception handler of eval pops the control frame pushed by Step 1. OVER POP!</li>
<li>The main exception handler pops the bottom control frame.</li>
<li>vm_push_frame() is called by error_print(), and it causes SEGV.</li>
</ol>
<p>The following patch seems to fix the problem, but I'm not sure.<br>
Could you check it, ko1?</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/compile.c b/compile.c
index 33e0ba3..c2a710a 100644
</span><span class="gd">--- a/compile.c
</span><span class="gi">+++ b/compile.c
</span><span class="p">@@ -2415,6 +2415,8 @@</span> static inline int
tailcallable_p(rb_iseq_t *iseq)
{
switch (iseq->body->type) {
<span class="gi">+ case ISEQ_TYPE_EVAL:
+ /* eval can't tail call because cfp will be over popped */
</span> case ISEQ_TYPE_RESCUE:
case ISEQ_TYPE_ENSURE:
/* rescue block can't tail call because of errinfo */
</code></pre> Ruby master - Bug #12576: SEGV when interrupting tail recursionhttps://bugs.ruby-lang.org/issues/12576?journal_id=595842016-07-11T01:28:58Zshugo (Shugo Maeda)
<ul></ul><p>Shugo Maeda wrote:</p>
<blockquote>
<p>The following patch seems to fix the problem, but I'm not sure.<br>
Could you check it, ko1?</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/compile.c b/compile.c
index 33e0ba3..c2a710a 100644
</span><span class="gd">--- a/compile.c
</span><span class="gi">+++ b/compile.c
</span><span class="p">@@ -2415,6 +2415,8 @@</span> static inline int
tailcallable_p(rb_iseq_t *iseq)
{
switch (iseq->body->type) {
<span class="gi">+ case ISEQ_TYPE_EVAL:
+ /* eval can't tail call because cfp will be over popped */
</span> case ISEQ_TYPE_RESCUE:
case ISEQ_TYPE_ENSURE:
/* rescue block can't tail call because of errinfo */
</code></pre>
</blockquote>
<p>load and main have the same problem, so ISEQ_TYPE_TOP and ISEQ_TYPE_MAIN should be added.</p> Ruby master - Bug #12576: SEGV when interrupting tail recursionhttps://bugs.ruby-lang.org/issues/12576?journal_id=613232016-11-05T15:35:12Zko1 (Koichi Sasada)
<ul></ul><p>sorry for long absence. I agree with your suggestion. Could you commit it?</p> Ruby master - Bug #12576: SEGV when interrupting tail recursionhttps://bugs.ruby-lang.org/issues/12576?journal_id=613322016-11-05T16:22:07Zshugo (Shugo Maeda)
<ul><li><strong>Assignee</strong> changed from <i>ko1 (Koichi Sasada)</i> to <i>shugo (Shugo Maeda)</i></li></ul> Ruby master - Bug #12576: SEGV when interrupting tail recursionhttps://bugs.ruby-lang.org/issues/12576?journal_id=613382016-11-05T16:42:33Zshugo (Shugo Maeda)
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>Applied in changeset r56610.</p>
<hr>
<ul>
<li>compile.c (tailcallable_p): disable tail call optimization for<br>
toplevel, eval, and load to avoid SEGV when interrupted by SIGINT.<br>
<a href="/issues/12576">[ruby-core:76327]</a> [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: SEGV when interrupting tail recursion (Closed)" href="https://bugs.ruby-lang.org/issues/12576">#12576</a>]</li>
</ul>