[LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection

Dan Gohman dan433584 at gmail.com
Thu Nov 29 10:46:05 PST 2012


On Wed, Nov 28, 2012 at 10:54 PM, Dmitry N. Mikushin <maemarcus at gmail.com>wrote:

> Dear all,
>
> Consider there is a program that writes to stdout using two different
> raw_fd_ostream-s:


raw_fd_ostream does buffered I/O, so it's not really meant to be used like
this.


> #include "llvm/LLVMContext.h"
> #include "llvm/Module.h"
> #include "llvm/Support/raw_ostream.h"
>
> using namespace llvm;
>
> int main()
> {
>         raw_fd_ostream S(STDOUT_FILENO, false);
>
>         outs() << "Hello";
>         S << ", world!";
>
>         return 0;
> }
>
> With this layout everything is fine, it prints ", world!Hello"
>

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.


>
> Now, make S definition global:
>
> #include "llvm/LLVMContext.h"
> #include "llvm/Module.h"
> #include "llvm/Support/raw_ostream.h"
>
> using namespace llvm;
>
> raw_fd_ostream S(STDOUT_FILENO, false);
>
> int main()
> {
>         outs() << "Hello";
>         S << ", world!";
>
>         return 0;
> }
>
> And... surprisingly:
>
> $ ./outs
> Hello, world!$ ./outs &>result
> $ cat result
> HelloLLVM ERROR: IO failure on output stream.
>
> So, no error with screen output and error when redirected to file. Why so?


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.

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.

Dan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121129/8989238e/attachment.html>


More information about the llvm-dev mailing list