Dmitry N. Mikushin
2012-Nov-29 19:03 UTC
[LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection
Hi Dan, Sean, Thanks for replies, So does it mean user is not expected to use any other stream for stdout, but outs()? Although there is a comment "If you don't want this behavior, don't use outs().", outs() is a static instance which always exists and creates problems, even if not used. - D. 2012/11/29 Dan Gohman <dan433584 at gmail.com>> 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/9d389b1e/attachment.html>
Dan Gohman
2012-Nov-29 21:20 UTC
[LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection
On Thu, Nov 29, 2012 at 11:03 AM, Dmitry N. Mikushin <maemarcus at gmail.com>wrote:> Hi Dan, Sean, > > Thanks for replies, > > So does it mean user is not expected to use any other stream for stdout, > but outs()? Although there is a comment "If you don't want this behavior, > don't use outs().", outs() is a static instance which always exists and > creates problems, even if not used.If you don't call outs(), its static object isn't constructed (or destructed). Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121129/54537be9/attachment.html>
Dmitry N. Mikushin
2012-Nov-29 21:26 UTC
[LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection
Right, thank you! 2012/11/29 Dan Gohman <dan433584 at gmail.com>> On Thu, Nov 29, 2012 at 11:03 AM, Dmitry N. Mikushin <maemarcus at gmail.com>wrote: > >> Hi Dan, Sean, >> >> Thanks for replies, >> >> So does it mean user is not expected to use any other stream for stdout, >> but outs()? Although there is a comment "If you don't want this behavior, >> don't use outs().", outs() is a static instance which always exists and >> creates problems, even if not used. > > > If you don't call outs(), its static object isn't constructed (or > destructed). > > Dan > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121129/ee1a7cb3/attachment.html>
Reasonably Related Threads
- [LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection
- [LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection
- [LLVMdev] Different behavoir when writing to stdout with 2 raw_fd_ostreams with or w/o redirection
- [LLVMdev] llvm-gfortran problems
- [LLVMdev] [NVPTX] Backend failure in LegalizeDAG due to unimplemented expand in target lowering