On Wed, Nov 28, 2012 at 10:54 PM, Dmitry N. Mikushin <span dir="ltr"><<a href="mailto:maemarcus@gmail.com" target="_blank">maemarcus@gmail.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Dear all,<br><br>Consider there is a program that writes to stdout using two different raw_fd_ostream-s:</blockquote><div> </div><div>raw_fd_ostream does buffered I/O, so it's not really meant to be used like this.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br><span style="font-family:courier new,monospace">#include "llvm/LLVMContext.h"<br>#include "llvm/Module.h"<br>

#include "llvm/Support/raw_ostream.h"<br><br>using namespace llvm;<br><br>int main()<br>{<br>        raw_fd_ostream S(STDOUT_FILENO, false);<br><br>        outs() << "Hello";<br>        S << ", world!";<br>

<br>        return 0;<br>}</span><br><br>With this layout everything is fine, it prints ", world!Hello"<br></blockquote><div><br></div><div>Yes. raw_ostream does buffering. The output you see is a classic symptom of having two different buffers for the same file descriptor. You can make this work by manually flushing when switching from one buffer to another, if you're careful.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>Now, make S definition global:<br><br><span style="font-family:courier new,monospace">#include "llvm/LLVMContext.h"<br>

#include "llvm/Module.h"<br>#include "llvm/Support/raw_ostream.h"<br><br>using namespace llvm;<br><br>raw_fd_ostream S(STDOUT_FILENO, false);<br><br>int main()<br>{<br>        outs() << "Hello";<br>

        S << ", world!";<br><br>        return 0;<br>}</span><br><br>And... surprisingly:<br><br><span style="font-family:courier new,monospace">$ ./outs <br>Hello, world!$ ./outs &>result<br>$ cat result <br>

HelloLLVM ERROR: IO failure on output stream.</span><br><br>So, no error with screen output and error when redirected to file. Why so?</blockquote><div><br></div><div>The difference in output is due to the difference in when the buffers happen to get destructed, because they flush their buffers in their destructors.</div>
<div><br></div><div>The error comes from the fact that outs() closes STDOUT_FILENO when the program exits. Your other raw_fd_ostream is getting unlucky and having its destructor run after the outs() object is destructed, so it ends up trying to write to a closed file descriptor. There's no easy way to avoid this problem, as global destructor ordering is inconvenient to control. In general, it's best to try to avoid this situation altogether.</div>
<div> </div><div>Dan</div><div><br></div></div>