[cfe-dev] libclang locking files for write/delete on windows

Kim Gräsman kim.grasman at gmail.com
Tue Dec 9 12:52:55 PST 2014


Hi Ivan,

> The issue seems definetly linked to file size. I took dummy.h and ran it through the monitor. (bad trace)
> Then I took dummy.h, removed 90% of the lines from the bottom, and also ran it through the monitor. (good trace)
> [...]
> Around some function called llvm MemoryBuffer getOpenFile things start to go different.
> I have no experience yet with llvm code base to pinpoint this.

This is good info; MemoryBuffer::getOpenFile conditionally uses file
mappings or normal file reads depending on file size (see
MemoryBuffer.cpp/shouldUseMmap).

Since the mapping uses a stricter sharing mode than the normal file
read, it's more likely to fail. Still not sure who's writing/deleting
the file while Clang attempts to map it, can you make that out from
your PM logs?

Also, I think I found a bug in MemoryBuffer:

Index: lib/Support/MemoryBuffer.cpp
===================================================================
--- lib/Support/MemoryBuffer.cpp        (revision 219027)
+++ lib/Support/MemoryBuffer.cpp        (working copy)
@@ -185,7 +185,7 @@

 public:
   MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
-                       uint64_t Offset, std::error_code EC)
+                       uint64_t Offset, std::error_code &EC)
       : MFR(FD, false, sys::fs::mapped_file_region::readonly,
             getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
     if (!EC) {

If the error code were to be passed by value, the calling code seems
meaningless:

    std::error_code EC;
    std::unique_ptr<MemoryBuffer> Result(
        new (NamedBufferAlloc(Filename))
        MemoryBufferMMapFile(RequiresNullTerminator, FD, MapSize, Offset, EC));
    if (!EC)
      return std::move(Result);

That is, if mapping fails, we get an empty buffer back instead of
falling through.

- Kim



More information about the cfe-dev mailing list