https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112017-09-15T08:13:46ZRuby Issue Tracking SystemRuby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=666882017-09-15T08:13:46Zh.shirosaki (Hiroshi Shirosaki)h.shirosaki@gmail.com
<ul><li><strong>ruby -v</strong> set to <i>ruby 2.5.0dev (2017-09-11 trunk 59829) [x64-mingw32]</i></li></ul><p>Segmentation fault is caused by <code>RBASIC_CLASS(err)</code> access in hook_before_rewind() in vm.c:1667.<br>
<code>err</code> is not a valid pointer.</p>
<p>Here is gdb output.</p>
<pre><code>Run options: "--ruby=./miniruby.exe -I../snapshot/lib -I. -I.ext/common ../snapshot/tool/runruby.rb --extout=.ext --debugger -- --disable-gems" --excludes-dir=../snapshot/test/excludes --name=!/memory_leak/ -v -ntest_closed_read
# Running tests:
[1/1] TestSocket#test_closed_read[New Thread 16292.0x331c]
[New Thread 16292.0x57f4]
[Thread 16292.0x331c exited with code 0]
Thread 9 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 16292.0x57f4]
0x00000000680aad1a in hook_before_rewind (th=th@entry=0x33671d0, will_finish_vm_exec=will_finish_vm_exec@entry=0, state=6, err=err@entry=0xc0000241,
cfp=<optimized out>) at ../snapshot/vm.c:1667
1667 if (state == TAG_RAISE && RBASIC_CLASS(err) == rb_eSysStackError) {
(gdb) bt
#0 0x00000000680aad1a in hook_before_rewind (th=th@entry=0x33671d0, will_finish_vm_exec=will_finish_vm_exec@entry=0, state=6, err=err@entry=0xc0000241,
cfp=<optimized out>) at ../snapshot/vm.c:1667
#1 0x00000000680b6ffd in vm_exec (th=0x31e000, th@entry=0x33671d0) at ../snapshot/vm.c:2003
...
</code></pre>
<p><code>err</code> seems to come from rb_threadptr_execute_interrupts() in thread.c.<br>
Adding volatile as the following suppresses segfault on my test.<br>
But this patch sometimes causes another error (TypeError: exception class/object expected).<br>
I don't know the reason.</p>
<pre><code class="patch syntaxhl" data-language="patch"><span class="gh">diff --git a/thread.c b/thread.c
index d706ee469b..fd1ee78933 100644
</span><span class="gd">--- a/thread.c
</span><span class="gi">+++ b/thread.c
</span><span class="p">@@ -2058,7 +2058,7 @@</span> rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
/* exception from another thread */
if (pending_interrupt && rb_threadptr_pending_interrupt_active_p(th)) {
<span class="gd">- VALUE err = rb_threadptr_pending_interrupt_deque(th, blocking_timing ? INTERRUPT_ON_BLOCKING : INTERRUPT_NONE);
</span><span class="gi">+ volatile VALUE err = rb_threadptr_pending_interrupt_deque(th, blocking_timing ? INTERRUPT_ON_BLOCKING : INTERRUPT_NONE);
</span> thread_debug("rb_thread_execute_interrupts: %"PRIdVALUE"\n", err);
if (err == Qundef) {
</code></pre>
<pre><code> 1) Failure:
TestSocket#test_closed_read [C:/Users/h.shirosaki/work/rubyinstaller2-packages/mingw-w64-ruby25/src/snapshot/test/socket/test_socket.rb:543]:
<a href="/issues/4390">[ruby-core:35203]</a>.
[IOError] exception expected, not.
Class: <TypeError>
Message: <"exception class/object expected">
---Backtrace---
C:/Users/h.shirosaki/work/rubyinstaller2-packages/mingw-w64-ruby25/src/snapshot/test/socket/test_socket.rb:537:in `readline'
C:/Users/h.shirosaki/work/rubyinstaller2-packages/mingw-w64-ruby25/src/snapshot/test/socket/test_socket.rb:537:in `block in test_closed_read'
---------------
</code></pre> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=668182017-09-21T10:36:37Zh.shirosaki (Hiroshi Shirosaki)h.shirosaki@gmail.com
<ul><li><strong>File</strong> <a href="/attachments/6750">0001-io.c-fix-segfault-with-closing-socket-on-MinGW.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/6750/0001-io.c-fix-segfault-with-closing-socket-on-MinGW.patch">0001-io.c-fix-segfault-with-closing-socket-on-MinGW.patch</a> added</li></ul><p>I found that another exception raises while executing rb_exc_raise() in rb_threadptr_execute_interrupts().<br>
This reentering exception would cause segfault for some reason.<br>
Socket is closed releasing GVL before rb_exc_raise() in rb_threadptr_execute_interrupts().<br>
If keeping GVL with close, reentering exception and segfault is not raised on my test. The patch is attached.<br>
This may be related to <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: TestSocket#test_closed_read fails after r31230 (Closed)" href="https://bugs.ruby-lang.org/issues/4558">#4558</a>?</p> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=668192017-09-21T11:39:33Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<ul></ul><p>Shirosaki-san, your patch seems ok.<br>
Could you check in?</p> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=668212017-09-21T13:49:46ZMSP-Greg (Greg L)
<ul></ul><p>Shirosaki-san,</p>
<p>'Breakfast build' is finished, passed <code>test-all</code>, and the following also passed:</p>
<pre><code>ruby runner.rb -I../lib -I. --repeat-count=50 --show-skip socket/test_socket.rb -ntest_closed_read
</code></pre>
<p>This has been an intermittent failure, but I've never had it complete 50 before.</p>
<p>Hence, along with usa, I believe you've fixed the issue. Thanks again for your work.</p>
<p>I'm not sure how everyone would prefer to be addressed. If you'd like to address me, please call me Greg. The first code I wrote was on a teletype...</p>
<p>EDIT: A little rushed this morning.</p>
<p>I applied the patch to:</p>
<pre><code>ruby 2.5.0dev (2017-09-21 trunk 59985) [x64-mingw32]
</code></pre>
<p>I checked previous builds (<strong>without</strong> the patch), the following builds failed:</p>
<pre><code>ruby 2.5.0dev (2017-09-20 trunk 59974) [x64-mingw32] (previous build without patch)
ruby 2.4.2p198 (2017-09-14 revision 59899) [x64-mingw32]
ruby 2.3.5p376 (2017-09-14 revision 59905) [x64-mingw32]
</code></pre>
<p>I don't know if this could be backported or not...</p> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=669682017-09-28T13:43:33ZAnonymous
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset trunk|r60055.</p>
<hr>
<p>io.c: fix segfault with closing socket on Windows</p>
<ul>
<li>io.c (fptr_finalize_flush): add an argument to keep GVL.</li>
<li>io.c (fptr_finalize): adjust for above change.</li>
<li>io.c (io_close_fptr): closing without GVL causes another<br>
exception while raising exception in another thread. This causes<br>
segfault on Windows. Keep GVL while closing when another thread<br>
raises.<br>
[Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: MinGW / mswin intermittent failure in test/socket/test_socket.rb (Closed)" href="https://bugs.ruby-lang.org/issues/13856">#13856</a>] <a href="/issues/13856">[ruby-core:82602]</a></li>
</ul> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=669942017-09-29T11:18:12Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Backport</strong> changed from <i>2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN</i> to <i>2.2: UNKNOWN, 2.3: REQUIRED, 2.4: REQUIRED</i></li></ul> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=708352018-03-07T14:05:48Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Backport</strong> changed from <i>2.2: UNKNOWN, 2.3: REQUIRED, 2.4: REQUIRED</i> to <i>2.2: UNKNOWN, 2.3: REQUIRED, 2.4: DONE</i></li></ul><p>ruby_2_4 r62690 merged revision(s) 60055.</p> Ruby master - Bug #13856: MinGW / mswin intermittent failure in test/socket/test_socket.rbhttps://bugs.ruby-lang.org/issues/13856?journal_id=710712018-03-18T15:07:27Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<ul><li><strong>Backport</strong> changed from <i>2.2: UNKNOWN, 2.3: REQUIRED, 2.4: DONE</i> to <i>2.2: UNKNOWN, 2.3: DONE, 2.4: DONE</i></li></ul><p>ruby_2_3 r62821 merged revision(s) 60055.</p>