[llvm-bugs] [Bug 47087] New: std::ifstream makes an unwarranted read, thereby blocking when it shouldn't in a certain case

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Aug 10 02:30:31 PDT 2020


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: unassignedclangbugs at nondot.org
          Reporter: victor.dods at gmail.com
                CC: llvm-bugs at lists.llvm.org, mclow.lists at 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200810/27ded6b7/attachment.html>


More information about the llvm-bugs mailing list