https://bugs.llvm.org/show_bug.cgi?id=47087
Bug ID: 47087
Summary: std::ifstream makes an unwarranted read, thereby
blocking when it shouldn't in a certain case
Product: libc++
Version: 10.0
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Standards Issues
Assignee: unassignedclangb...@nondot.org
Reporter: victor.d...@gmail.com
CC: llvm-bugs@lists.llvm.org, mclow.li...@gmail.com
Created attachment 23835
--> https://bugs.llvm.org/attachment.cgi?id=23835&action=edit
Source code for "named pipes process" for reproducing bug
In working with named pipes (via mkfifo), I've run across a bug in libc++
(relative to what seems to be expected, working behavior in libstdc++)
regarding std::ifstream's buffering behavior.
In particular, two fifos are created, and two processes open them, one for
sending data in each direction. There is an exchange of data, each process
taking turns reading from the respective fifo. But certain read operations
block, apparently due to an extra read happening.
Here are the reproduction instructions. I've also attached source code and a
build script. I'm using g++-8 and clang++-10 here, but I imagine it doesn't
matter exactly what versions of the compilers are, so long as they're
compatible with libc++ and libstdc++.
Instructions follow:
Compile using each compiler, against each C++ std lib implementation.
build.sh follows (indentation only for clarity):
#!/bin/bash -ex
# Compile with clang++-10, link to libc++
clang++-10 -stdlib=libc++ -g -std=c++17 namedpipes.cpp -o
namedpipes.clang++-10.libc++
# Compile with clang++-10, link to libstdc++
clang++-10 -stdlib=libstdc++ -g -std=c++17 namedpipes.cpp -o
namedpipes.clang++-10.libstdc++ -lstdc++fs
# Compile with g++-8, link to libstdc++
g++-8 -std=c++17 -g -rdynamic namedpipes.cpp -o namedpipes.g++-8.libstdc++
-lstdc++fs
# Compile with g++-8, link to libc++
# Note that it's nontrivial to get g++ to link libc++.
# See https://libcxx.llvm.org/docs/UsingLibcxx.html#using-libc-with-gcc
LIBCPP_INCLUDE_DIR=/usr/lib/llvm-10/include/c++/v1
g++-8 -std=c++17 -nostdinc++ -I${LIBCPP_INCLUDE_DIR} -g -rdynamic
namedpipes.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc -o
namedpipes.g++-8.libc++
Note that the bug here is happening against libc++.
Run as a pair of processes, one in each terminal.
./namedpipes.g++-8.libstdc++ p0
./namedpipes.g++-8.libstdc++ p1
The g++-8 libstdc++ one works as expected.
Run as a pair of processes, one in each terminal, each one run under strace.
strace ./namedpipes.clang++-10.libc++ p0
strace ./namedpipes.clang++-10.libc++ p1
You'll see that p0 blocks with
write(2, "p0: about to read ... ", 22p0: about to read ... ) = 22
fstat(4, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
read(4,
and p1 blocks with
write(2, "p1: about to read ... ", 22p1: about to read ... ) = 22
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
read(3, "a", 4096) = 1
read(3,
where the last read() is the unwarranted, blocking one that's causing the
problems.
If you run the g++ binaries under strace, you'll see that p1 does not block:
write(2, "p1: about to read ... ", 22p1: about to read ... ) = 22
read(3, "a", 1) = 1
write(2, "success; read '", 15success; read ') = 15
Notice that there was only one call to read(), so it didn't block.
The same holds when you switch the compiler but keep the C++ std lib choice the
same,
i.e. libstdc++ works as expected, and libc++ blocks.
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs