<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Windows llvm::sys::fs::remove algorithm is *VERY* subtly incorrect, resulting in unpredictable "directory not empty" errors"
   href="https://llvm.org/bugs/show_bug.cgi?id=27386">27386</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Windows llvm::sys::fs::remove algorithm is *VERY* subtly incorrect, resulting in unpredictable "directory not empty" errors
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </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>Support Libraries
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>test35965@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=16224" name="attach_16224" title="The MSBuild output of two tests failing because of this bug. There's a third failure (tools/llvm-symbolizer/ppc64.test), unrelated to this bug.">attachment 16224</a> <a href="attachment.cgi?id=16224&action=edit" title="The MSBuild output of two tests failing because of this bug. There's a third failure (tools/llvm-symbolizer/ppc64.test), unrelated to this bug.">[details]</a></span>
The MSBuild output of two tests failing because of this bug. There's a third
failure (tools/llvm-symbolizer/ppc64.test), unrelated to this bug.

Under heavy IO load, removing directories on Windows with llvm::sys::fs:remove
will fail unpredictably.

I've just observed the TestWriteWithSystemEncoding test in
./llvm/unittests/Support/ProgramTest.cpp failing because of this. That test
creates a kinda-unique directory named "program-test-%%%%%%" (where % is a
pseudorandom alphanumeric), creates a file named "international-file.txt" in
it, and roundtrip-tests some text (writes some text with one encoding, reads it
with another, checks if it's not garbled). After that, it deletes the file
(llvm::sys::fs::remove(file_pathname.str())) and then the directory
(llvm::sys::fs::remove(TestDirectory.str())). Essentially, when Windows
"Deletes" a file, it doesn't actually Delete the file; when the system is under
load, "international-file.txt" may STILL be in the directory by the time of
llvm::sys::fs::remove(TestDirectory.str()).



The details of WHY this will fail are very counter-intuitive, and you should
see "CppCon 2015: Niall Douglas â€śRacing The File System"
(<a href="https://youtu.be/uhRWMGBjlO8?t=7m35s">https://youtu.be/uhRWMGBjlO8?t=7m35s</a>) for *specifically* why the code is
wrong. Lots of programs get this wrong, Douglas mentions CPython, and I've seen
it in Chromium.



Sidenote: The documentation for RemoveDirectory
(<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365488.aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa365488.aspx</a>) is
kinda crappy, because it says "RemoveDirectory removes a directory junction,
even if the contents of the target are not empty; the function removes
directory junctions regardless of the state of the target object.", but
"Creating and Deleting Directories"
(<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa363872.aspx">https://msdn.microsoft.com/en-us/library/windows/desktop/aa363872.aspx</a>) says:
"To delete an existing directory, use the RemoveDirectory or
RemoveDirectoryTransacted function. Before removing a directory, you must
ensure that the directory is empty and that you have the delete access
privilege for the directory. To do the latter, call the GetSecurityInfo
function."</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>