[LLVMdev] Behaviour of outs()?
mats petersson
mats at planetcatfish.com
Fri Jan 23 11:07:27 PST 2015
I can confirm that llvm/clang does not output anything to stdout, but
the fix of setting shoulClose to false solves the problem. When I
dissassembled my clang, it shows 137 occurrences of _ZN4llvm4outsEv (a
few are the actual `outs` function itself, but I thing 134 actual
calls are made - I did not check if any of those are done in a scope
that doesn't actually write to the resulting stream, but I expect that
is what happens).
Exact strace:
... thousands of other lines removed...
munmap(0xb46e4000, 3149824) = 0
close(1) = 0
munmap(0xb1524000, 528384) = 0
write(1, "<elided as irrelevant>", 391) = -1 EBADF (Bad file descriptor)
As you can see, it's not "far off" that it works - only two system
calls apart... And it is the ONLY write with filenumber 1.
--
Mats
On 23 January 2015 at 18:41, mats petersson <mats at planetcatfish.com> wrote:
> So, I'm only "fixing the compiler code" (by setting `shouldClose =
> false`), but in essence the code we have is something like this (much
> simplified):
>
> int main(...)
> {
> printf("Some stuff\n");
> ...
> use_clang_to_compile_opencl();
> run_opencl();
> ..
> printf("Some more stuff\n");
> }
>
> and then `myprog > file.txt`
>
> In this case, clang and llvm do not output anything (as far as I'm
> aware), but the "Some stuff" and "Some more stuff" does not appear in
> file.txt. Using strace, my colleague found the problem as `close(1)`
> followed by `write(1, "...") = EBADF`.
>
>
> [The ACTUAL code is a benchmark that is part of our test-code, and the
> test is failing]
>
> I'm fairly sure that whether llvm actually uses `outs` or not, it will
> be constructed and destroyed based on it's existance. I will have a
> look at this in more detail, but the general question still remains:
>
> Should LLVM close `STDOUT_FILENO` in a destructor? I don't think so. If so, why?
>
> --
> Mats
>
> On 23 January 2015 at 18:20, Duncan P. N. Exon Smith
> <dexonsmith at apple.com> wrote:
>>
>>> On 2015-Jan-23, at 09:52, mats petersson <mats at planetcatfish.com> wrote:
>>>
>>> I was just fixing a bug that was caused by `stdout` being closed
>>> before the runtime has done `fflush(stdout)` [or however this is
>>> implemented in the runtime].
>>>
>>> The cause of this seems to be that `outs()` returns a static object
>>> created from `raw_fd_stream(STDOUT_FILENO, true)` - the `true` being
>>> the `shouldClose` parameter.
>>>
>>> Surely LLVM is not supposed to close `stdout` as part of its operations?
>>
>> Looks like this was added in r111643:
>>
>> commit 5d56d9df928c48571980efe8d4205de8ab557b7c
>> Author: Dan Gohman <gohman at apple.com>
>> Date: Fri Aug 20 16:44:56 2010 +0000
>>
>> Make outs() close its file when its stream is destructed, so that
>> pending output errors are detected.
>>
>>
>> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111643 91177308-0d34-0410-b5e6-96231b3b80d8
>>
>> Certainly looks intentional. Comment in the code is:
>>
>> // Delete the file descriptor when the program exits, forcing error
>> // detection. If you don't want this behavior, don't use outs().
>>
>> I don't really have an opinion on whether this is a good idea, but it
>> does suggest that any use of `outs()` in `lib/` is a bug.
>>
>> $ git grep -l 'outs()' -- lib/
>> lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
>> lib/IR/GCOV.cpp
>> lib/Support/CommandLine.cpp
>> lib/Support/FormattedStream.cpp
>> lib/Support/TargetRegistry.cpp
>> lib/Support/raw_ostream.cpp
>> lib/Target/CppBackend/CPPBackend.cpp
>>
>> All of these cases seem to be for outputting help text of some sort. But
>> probably they should be passed a reference to a `raw_ostream`, so that the
>> caller gets to choose whether or not to use `outs()`.
>>
>> Were you hitting one of these?
More information about the llvm-dev
mailing list