https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112009-02-15T06:31:07ZRuby Issue Tracking SystemRuby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=32202009-02-15T06:31:07Zcfis (Charlie Savage)
<ul></ul><p>=begin<br>
Microsoft documentation is at:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/aa364439.aspx" class="external">http://msdn.microsoft.com/en-us/library/aa364439.aspx</a><br>
=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=32262009-02-15T11:57:24Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Sun, 15 Feb 2009 06:27:35 +0900,<br>
Charlie Savage wrote in <a href="/issues/1162">[ruby-core:22116]</a>:</p>
<blockquote>
<p>Failure occurs when running miniruby.exe for the first time:</p>
<p>File: f:\dd\vctools\crt_bld\self_x86\src\commit.c, line 69.<br>
Expression: ("Invalid file descriptor. File possibly closed by a different thread", 0)</p>
</blockquote>
<p>It's false assertion. Report it to Microsoft.</p>
<p>--<br>
Nobu Nakada</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=32282009-02-15T16:26:07Zcfis (Charlie Savage)
<ul></ul><p>=begin<br>
Hi Nobu,</p>
<p>The error message is poor, but this is still a bug in ruby. Let me show you the code:</p>
<p>Starting at Visual Studio 9.0\VC\crt\src\commit.c, line 51:</p>
<pre><code> if ( !FlushFileBuffers((HANDLE)_get_osfhandle(filedes)) ) {
retval = GetLastError();
}
else {
retval = 0; /* return success */
}
/* map the OS return code to C errno value and return code */
if (retval == 0)
goto good;
_doserrno = retval;
}
errno = EBADF;
retval = -1;
_ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
</code></pre>
<p>As Microsoft's documentation states (see link above), it is incorrect to pass stdout or stderr to FlushFileBuffers. Therefore FlushFileBuffers fails and retval is set to 6 via the call to GetLastError. From <a href="http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx</a>:</p>
<p>ERROR_INVALID_HANDLE 6 0x6</p>
<p>So the assertion fails. Bad error message I agree, but still a bug in Ruby.</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=32292009-02-16T00:15:03Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Sun, 15 Feb 2009 16:24:24 +0900,<br>
Charlie Savage wrote in <a href="https://blade.ruby-lang.org/ruby-core/22134">[ruby-core:22134]</a>:</p>
<blockquote>
<p>As Microsoft's documentation states (see link above), it is<br>
incorrect to pass stdout or stderr to FlushFileBuffers.<br>
Therefore FlushFileBuffers fails and retval is set to 6 via<br>
the call to GetLastError. From<br>
<a href="http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/ms681382(VS.85).aspx</a>:</p>
</blockquote>
<p>Yes, it's a reasonable and expected behavior.</p>
<blockquote>
<p>So the assertion fails. Bad error message I agree, but still a bug in Ruby.</p>
</blockquote>
<p>It's not a bug, the file descriptor is not invalid, nor closed.<br>
Just a false positive assertion, e.g., a bug of msvcrt.</p>
<p>--<br>
Nobu Nakada</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=32302009-02-16T01:27:06Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>=begin<br>
Applied in changeset r22333.<br>
=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=32322009-02-16T07:42:38Zcfis (Charlie Savage)
<ul></ul><p>=begin<br>
Hi Nobu,</p>
<p>Thanks for your help on this.</p>
<p>However, I think your patch is the wrong approach. If I understand the intention correctly, it is meant to stub out all crt debug messages. Is such a strong remedy needed to solve this one issue? Take for example the other VC++ bug I submitted about the unassigned variable - your patch would hide it (assuming I am understanding the patch correctly). Or what about more serious issues such as using ALLOC in tandem with free instead of xfree on the Windows platform? Do we want to disable those also?</p>
<p>The other problem with the patch is that it doesn't actually work. To test it I applied to locally. The assertion error does not go away and it still not possible to build Ruby with the -RTC1 flag.</p>
<p>So would you be willing to revert this patch?</p>
<p>As for the original problem, I'll make my pitch one more time and then if you still disagree I'll just have to patch my own version of ruby 1.9.1. Quoting MSDN - <a href="http://msdn.microsoft.com/en-us/library/aa364439(VS.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/aa364439(VS.85).aspx</a>.</p>
<p>"The function fails if hFile is a handle to the console output. That is because the console output is not buffered. The function returns FALSE, and GetLastError returns ERROR_INVALID_HANDLE."</p>
<p>Seeing that Microsoft's documentation says it invalid to pass stdout or stderr to FlushFileBuffers, and _commit calls FlushFileBuffers, I have a hard time seeing that this is a bug in msvcrt.</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=33102009-02-23T12:01:15Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Mon, 16 Feb 2009 07:40:51 +0900,<br>
Charlie Savage wrote in <a href="https://blade.ruby-lang.org/ruby-core/22170">[ruby-core:22170]</a>:</p>
<blockquote>
<p>The other problem with the patch is that it doesn't actually<br>
work. To test it I applied to locally. The assertion error<br>
does not go away and it still not possible to build Ruby with<br>
the -RTC1 flag.</p>
</blockquote>
<p>It is a compile time flag and irrelevant to debug built msvcrt.</p>
<blockquote>
<p>As for the original problem, I'll make my pitch one more time<br>
and then if you still disagree I'll just have to patch my own<br>
version of ruby 1.9.1. Quoting MSDN -<br>
<a href="http://msdn.microsoft.com/en-us/library/aa364439(VS.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/aa364439(VS.85).aspx</a>.</p>
</blockquote>
<p>It does mention about FlushFileBuffers() only, not _commit().<br>
And says just it returns an error, not make the process<br>
crashed.</p>
<blockquote>
<p>Seeing that Microsoft's documentation says it invalid to pass<br>
stdout or stderr to FlushFileBuffers, and _commit calls<br>
FlushFileBuffers, I have a hard time seeing that this is a<br>
bug in msvcrt.</p>
</blockquote>
<p>Feel free to call it a bug or a paranoiac false assertion of<br>
msvcrt, and now disabled already, at r22337.</p>
<p>--<br>
Nobu Nakada</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=33112009-02-23T12:45:08Zcfis (Charlie Savage)
<ul></ul><p>=begin</p>
<blockquote>
<p>It is a compile time flag and irrelevant to debug built msvcrt.</p>
</blockquote>
<p>Not sure what you mean. VC2008 (and earlier versions) set the -RTC1 flag by default when creating debug builds of C/C++ projects. The -RTC1 flag causes the binary to use a debug version of the C runtime libraries. These libraries are helpful in diagnosing memory problems or other incorrect usages of the C runtime library.</p>
<p>Since the Ruby build process depends on creating a working version of miniruby.exe, setting -RTC1 means you can't build a debug version of Ruby because miniruby crashes when invoked with an assertion error.</p>
<blockquote>
<p>It does mention about FlushFileBuffers() only, not _commit().<br>
And says just it returns an error, not make the process<br>
crashed.</p>
</blockquote>
<p>Well commit calls FlushFileBuffers, so its seems that documentation is applicable. And when you look at the documentation for _commit it says <a href="http://msdn.microsoft.com/en-us/library/17618685(VS.80).aspx" class="external">http://msdn.microsoft.com/en-us/library/17618685(VS.80).aspx</a></p>
<p>If fd is an invalid file descriptor, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue...</p>
<p>In a debug build, execution is <em>not</em> allowed to continue because an assertion error is raised.</p>
<blockquote>
<p>Feel free to call it a bug or a paranoiac false assertion of<br>
msvcrt, and now disabled already, at r22337.</p>
</blockquote>
<p>r22337 does not fix the problem. Try it with a debug build using VC2008 using the standard values set by VC2008 (/Od /D "WIN32" /D "_DEBUG" /Gm /EHsc /RTC1 /MDd /W3 /c /ZI /TP). It will crash.</p>
<p>I still consider this a bug - Ruby is passing an invalid file handle to commit. In a release build this will generate a "Invalid handle error" error code which Ruby ignores. In a debug build it triggers an assertion failure that causes Ruby to crash.</p>
<p>Once again the fix is simple and only affects windows:</p>
<p>#ifdef _WIN32</p>
<ul>
<li>fsync(fptr->fd);</li>
</ul>
<ul>
<li>if (io != rb_stdout && io != rb_stderr)</li>
<li>
<pre><code> fsync(fptr->fd);
</code></pre>
</li>
</ul>
<p>#endif</p>
<p>The only new line of code is the if statement.</p>
<p>So, I really think this is the way to solve the problem and r22337 should be reverted.</p>
<p>Thanks,</p>
<p>Charlie</p>
<p>is used by default VC2008 is of</p>
<p>Yes, its a compile time flag. What do you mean though its irrelevant to a debug built msvcrt?<br>
=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=33142009-02-23T17:23:19Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>=begin<br>
Hi,</p>
<p>At Mon, 23 Feb 2009 12:44:32 +0900,<br>
Charlie Savage wrote in <a href="https://blade.ruby-lang.org/ruby-core/22345">[ruby-core:22345]</a>:</p>
<blockquote>
<blockquote>
<p>It is a compile time flag and irrelevant to debug built msvcrt.</p>
</blockquote>
<p>Not sure what you mean. VC2008 (and earlier versions) set<br>
the -RTC1 flag by default when creating debug builds of C/C++<br>
projects. The -RTC1 flag causes the binary to use a debug<br>
version of the C runtime libraries. These libraries are<br>
helpful in diagnosing memory problems or other incorrect<br>
usages of the C runtime library.</p>
</blockquote>
<p>You are wrong about -RTC1. It does emit checking code but<br>
doesn't imply to link with msvcrtd.lib. -MDd flag directs it.<br>
You can compile with -RTC1 and no -MDd.</p>
<p> > Well commit calls FlushFileBuffers, so its seems that</p>
<blockquote>
<p>documentation is applicable. And when you look at the<br>
documentation for _commit it says<br>
<a href="http://msdn.microsoft.com/en-us/library/17618685(VS.80).aspx" class="external">http://msdn.microsoft.com/en-us/library/17618685(VS.80).aspx</a></p>
</blockquote>
<p>That page describes nothing about the assertion.</p>
<blockquote>
<p>r22337 does not fix the problem. Try it with a debug build<br>
using VC2008 using the standard values set by VC2008 (/Od /D<br>
"WIN32" /D "_DEBUG" /Gm /EHsc /RTC1 /MDd /W3 /c /ZI /TP). It<br>
will crash.</p>
</blockquote>
<p>/EHsc and /TP are specific for C++. I could compile fine with<br>
RUNTIMEFLAG=-MDd OPTFLAGS="-Od -RTC1" DEBUGFLAGS="-D_DEBUG<br>
-DWIN32", and no assertion dialog. The dialog appeared by<br>
commenting out the line _CrtSetReportMode(_CRT_ASSERT, 0) in<br>
win32/win32.c:rb_w32_sysinit().</p>
<blockquote>
<p>Once again the fix is simple and only affects windows:</p>
</blockquote>
<p>Your ``fix'' simply doesn't work with other IOs. Try:</p>
<p>open("CONOUT$", "w").flush</p>
<p>--<br>
Nobu Nakada</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=33902009-02-28T18:38:33Zcfis (Charlie Savage)
<ul></ul><p>=begin<br>
Hi Nobu,</p>
<p>Sorry, I've been out the last few days.</p>
<blockquote>
<p>You are wrong about -RTC1. It does emit checking code but<br>
doesn't imply to link with msvcrtd.lib. -MDd flag directs it.<br>
You can compile with -RTC1 and no -MDd.</p>
</blockquote>
<p>Yes, I agree these are different things. I was just pointing out that a debug build in Visual Studio by default sets both of these flags (create a new project, look at the debug build flags).</p>
<blockquote>
<p>Your ``fix'' simply doesn't work with other IOs. Try:</p>
</blockquote>
<p>open("CONOUT$", "w").flush</p>
<p>Yes, that fails with the same assertion error, with or without my patch. And it fails for the exact same reason - you can't use _commit to flush CONOUT because its a console buffer.</p>
<p>As I've stated earlier, I think using _CrtSetReportMode is the wrong solution. First it simply ignores the problem and second it could potentially hide other, more serious issues.</p>
<p>Maybe there is a better solution we could come up with? The goal is not to call flush on console buffers on windows, because that either returns a ERROR_INVALID_HANDLE error or causes an assertion failure (when the executable is built with -RTC1). So either way you look at it, these calls on Windows are incorrect.</p>
<p>Is there some way that console buffers (STDERR, STDOUT, CONOUT) can be easily recognized? Maybe checking fptr->stdio_file (its NULL in your example)?</p>
<p>Thanks,</p>
<p>Charlie<br>
=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=40922009-05-26T21:16:21Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Closed</i> to <i>Open</i></li><li><strong>Assignee</strong> set to <i>wyhaines (Kirk Haines)</i></li></ul><p>=begin</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=133832010-09-14T16:38:56Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li></ul><p>=begin</p>
<p>=end</p> Ruby master - Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderrhttps://bugs.ruby-lang.org/issues/1162?journal_id=810912019-08-27T16:02:12Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Tracker</strong> changed from <i>Backport</i> to <i>Bug</i></li><li><strong>Project</strong> changed from <i>Backport186</i> to <i>Ruby master</i></li><li><strong>Description</strong> updated (<a title="View differences" href="/journals/81091/diff?detail_id=54599">diff</a>)</li><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li><li><strong>ruby -v</strong> set to <i>ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-mswin32_90]</i></li><li><strong>Backport</strong> set to <i>2.5: UNKNOWN, 2.6: UNKNOWN</i></li></ul>