<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - clang version 11.1.0 - SIGABRT from llvm::raw_fd_ostream::~raw_fd_ostream when stderr redirects to stdin"
href="https://bugs.llvm.org/show_bug.cgi?id=49463">49463</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>clang version 11.1.0 - SIGABRT from llvm::raw_fd_ostream::~raw_fd_ostream when stderr redirects to stdin
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>11.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Frontend
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>bertrand@jacquin.bzh
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>Hi,
The following command can be used to verify if a given option is supported by
$CC:
$CC -Werror -<option> -E -xc - -o /dev/null
(While -Werror is not required for all compiler, clang will always return 0
even if an option is not supported unless -Werror is also passed as an
argument, hence I will keep mentioning -Werror here).
When the option is recognized or supported a return code of 0 is expected, if
the option is not recognized or supported a return code of 1 is expected with
potential warning on stderr. This is useful in the context of Makefile or build
systems to probe which option can be used, for example, to remove a set of
warnings. Those usually redirect all I/O to /dev/null to prevent from polluting
input or output, and instead only rely on return code:
$CC -Werror -<option> -E -xc - -o /dev/null < /dev/null 1>&0 2>&0
Here is a example using gcc to assess if -Wmissing-field-initializers
(supported by gcc and clang), -Wclobbered (supported by gcc but not by clang)
and -Wfoobar (supported by neither gcc or clang) are supported (tested with gcc
from 6.5 to 10.2):
$ gcc -Werror -Wmissing-field-initializers -E -xc - -o /dev/null < /dev/null
1>&0 2>&0
$ echo $?
0
$ gcc -Werror -Wclobbered -E -xc - -o /dev/null < /dev/null 1>&0 2>&0
$ echo $?
0
$ gcc -Werror -Wfoobar -E -xc - -o /dev/null < /dev/null 1>&0 2>&0
$ echo $?
1
Here is the same example with clang 11.1.0:
$ clang -Werror -Wmissing-field-initializers -E -xc - -o /dev/null <
/dev/null 1>&0 2>&0
$ echo $?
0
$ clang -Werror -Wclobbered -E -xc - -o /dev/null < /dev/null 1>&0 2>&0
Aborted (core dumped)
$ echo $?
134
$ clang -Werror -Wfoobar -E -xc - -o /dev/null < /dev/null 1>&0 2>&0
Aborted (core dumped)
$ echo $?
134
The example show that clang triggers a SIGABRT if an option is not supported,
hence generating a warning and if stderr is redirected to stdin. Digging more
into this, I can see stdout does not matter in this case and only the
redirection of stderr to stdin (both /dev/null) triggers the SIGABRT.
Please note if explicit redirection of stderr to the same output as stdin does
not trigger SIGABRT:
$ clang -Werror -Wfoobar -E -xc - -o /dev/null < /dev/null 2> /dev/null
$ echo $?
1
Same applies with no redirection as all:
$ clang -Werror -Wfoobar -E -xc - -o /dev/null
error: unknown warning option '-Wfoobar'; did you mean '-Wformat'?
[-Werror,-Wunknown-warning-option]
$ echo $?
1
This specific behaviour can be observed with a more simple use case like:
$ clang --does-not-exist < /dev/null 2>&0
Aborted (core dumped)
$ echo $?
134
Here is a backtrack from gdb with `clang -Werror -Wclobbered -E -xc - -o
/dev/null < /dev/null 1>&0 2>&0`:
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at
/usr/src/debug/sys-libs/glibc-2.32-r8/glibc-2.32/sysdeps/unix/sysv/linux/raise.c:49
#1 0x00007f7a155205e8 in __GI_abort () at
/usr/src/debug/sys-libs/glibc-2.32-r8/glibc-2.32/stdlib/abort.c:100
#2 0x00007f7a1624960c in llvm::report_fatal_error (Reason=...,
GenCrashDiag=false)
at
/usr/src/debug/sys-devel/llvm-11.1.0/llvm/lib/Support/ErrorHandling.cpp:126
#3 0x00007f7a1624940a in llvm::report_fatal_error (Reason=...,
GenCrashDiag=false)
at
/usr/src/debug/sys-devel/llvm-11.1.0/llvm/lib/Support/ErrorHandling.cpp:87
#4 0x00007f7a1639a3fc in llvm::raw_fd_ostream::~raw_fd_ostream
(this=0x7f7a1c659ca0 <llvm::errs()::S>, __in_chrg=<optimized out>)
at
/usr/src/debug/sys-devel/llvm-11.1.0/llvm/lib/Support/raw_ostream.cpp:685
#5 0x00007f7a15539a13 in __run_exit_handlers (status=1, listp=0x7f7a156b6598
<__exit_funcs>, run_list_atexit=run_list_atexit@entry=true,
run_dtors=run_dtors@entry=true) at
/usr/src/debug/sys-libs/glibc-2.32-r8/glibc-2.32/stdlib/exit.c:108
#6 0x00007f7a15539bbc in __GI_exit (status=<optimized out>) at
/usr/src/debug/sys-libs/glibc-2.32-r8/glibc-2.32/stdlib/exit.c:139
#7 0x00007f7a15521e41 in __libc_start_main (main=0x55cb2487e3b3 <main(int,
char const**)>, argc=8, argv=0x7fff39b270e8, init=<optimized out>,
fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fff39b270d8) at
/usr/src/debug/sys-libs/glibc-2.32-r8/glibc-2.32/csu/libc-start.c:348
#8 0x000055cb2487a95a in _start ()
(gdb) fr 2
#2 0x00007f7a1624960c in llvm::report_fatal_error (Reason=...,
GenCrashDiag=false)
at
/usr/src/debug/sys-devel/llvm-11.1.0/llvm/lib/Support/ErrorHandling.cpp:126
126 abort();
(gdb) info args
Reason = @0x7fff39b26ee0: {
LHS = {
twine = 0x7fff39b26f40,
cString = 0x7fff39b26f40 " \315\340$\313U",
stdString = 0x7fff39b26f40,
stringRef = 0x7fff39b26f40,
smallString = 0x7fff39b26f40,
formatvObject = 0x7fff39b26f40,
character = 64 '@',
decUI = 967995200,
decI = 967995200,
decUL = 0x7fff39b26f40,
decL = 0x7fff39b26f40,
decULL = 0x7fff39b26f40,
decLL = 0x7fff39b26f40,
uHex = 0x7fff39b26f40
},
RHS = {
twine = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
cString = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>
"H\213E\370\311\303\220UH\211\345SH\203\354(H\211}\350H\211u\340H\211U\330H\211M\320H\213]\350H\213E\350H\211\307\350w'\366\377H\211\301H\213E\320H\211\302H\211\316H\211\337\350\"\367\364\377H\213U\330H\213M\340H\213E\350H\211\316H\211\307\350\207\004",
stdString = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
stringRef = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
smallString = 0x7f7a161e8809 <std::operator+<char,
std::char_traits<char>, std::allocator<char> >(char const*,
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
<span class="quote">>&&)+67>,</span >
formatvObject = 0x7f7a161e8809 <std::operator+<char,
std::char_traits<char>, std::allocator<char> >(char const*,
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
<span class="quote">>&&)+67>,</span >
character = 9 '\t',
decUI = 371099657,
decI = 371099657,
decUL = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
decL = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
decULL = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
decLL = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>,
uHex = 0x7f7a161e8809 <std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >&&)+67>
},
LHSKind = llvm::Twine::StdStringKind,
RHSKind = llvm::Twine::EmptyKind
}
GenCrashDiag = false
(gdb) fr 3
#3 0x00007f7a1624940a in llvm::report_fatal_error (Reason=...,
GenCrashDiag=false)
at
/usr/src/debug/sys-devel/llvm-11.1.0/llvm/lib/Support/ErrorHandling.cpp:87
87 report_fatal_error(Twine(Reason), GenCrashDiag);
(gdb) info args
Reason = @0x7fff39b26f40: {
static npos = 18446744073709551615,
_M_dataplus = {
<std::allocator<char>> = {
<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data
fields>},
members of std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >::_Alloc_hider:
_M_p = 0x55cb24e0cd20 "IO failure on output stream: Bad file descriptor"
},
_M_string_length = 48,
{
_M_local_buf = "0\000\000\000\000\000\000\000\062\236S\025z\177\000",
_M_allocated_capacity = 48
}
}
GenCrashDiag = false
(gdb) fr 4
#4 0x00007f7a1639a3fc in llvm::raw_fd_ostream::~raw_fd_ostream
(this=0x7f7a1c659ca0 <llvm::errs()::S>, __in_chrg=<optimized out>)
at
/usr/src/debug/sys-devel/llvm-11.1.0/llvm/lib/Support/raw_ostream.cpp:685
685 report_fatal_error("IO failure on output stream: " +
error().message(),
(gdb) info args
this = 0x7f7a1c659ca0 <llvm::errs()::S>
__in_chrg = <optimized out>
(gdb) print FD
$2 = 2
The "Bad file descriptor" issue seems to exist since clang 6.0 while only clang
11 (11.0.1 and 11.1.0) do trigger a SIGABRT.
Do you want me to provide a coredump ?</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>