<html>
    <head>
      <base href="http://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 --- - mmap lock problem"
   href="http://llvm.org/bugs/show_bug.cgi?id=20880">20880</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>mmap lock problem
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

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

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

        <tr>
          <th>OS</th>
          <td>Windows XP
          </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>libclang
          </td>
        </tr>

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

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

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>* libclang Report

I would like to file 2 bug reports and a separate request for possible
improvement.

The environment I am currently using is as follows:
  Windows 7(x64)
  GNU Emacs
  llvm trunk
  libclang.dll(x64) build by VS2013
  clang-server(using libclang.dll)

  emacs uses IPC between clang-server to provide code completions

  Flags used for clang_parseTranslationUnit and clang_reparseTranslationUnit
are
  CXTranslationUnit_PrecompiledPreamble |
CXTranslationUnit_CacheCompletionResults.

** <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - Need to add product version numbers"
   href="show_bug.cgi?id=1">Bug #1</a>

libclang filesystem uses mmap for any files larger than 16KB. The use of mmap
causes problems when using libclang's completion features via IPC.

Let's say we have files "foo.cpp" and "foo.hpp", and "foo.hpp" contains the
declaration of class Foo. Assume "foo.hpp" is larger than 16KB; this will cause
it to be allocated via mmap.

Then, while a CXTranslationUnit exists for class Foo, trying to save foo.hpp
after adding a new property to class Foo will fail. This is due to
CXTranslationUnit for foo.cpp still locking the file foo.hpp by
CreateFileMapping.

The decision to use mmap seems to be dictated by the function shouldUseMmap in
clang-trunk/llvm/lib/Support/MemoryBuffer.cpp, but I am suspecting that the
parameter IsVolatileSize passed into it can contain incorrect value.

The comments for getFile, getOpenFileSlice and getOpenFile functions in
clang-trunk/llvm/lib/Support/MemoryBuffer.h describe IsVolatileSize as intended
to be set to true if the code being parsed is undergoing change.

------------------------------------------------------------------------------
IsVolatileSize Set to true to indicate that the file size may be changing, e.g.
when libclang tries to parse while the user is editing/updating the file. 
------------------------------------------------------------------------------

So parsing while saving seems to be supported.

But there seems to be cases where the flag is set to false and as a result the
inclded files get locked. The cases where IsVolatileSize becomes false are:

- SrcMgr::ContentCache::IsSystemFile==true
- SourceManager is constructed with UserFilesAreVolatile==false

Even if IsSystemFile==false, when clang_reparseTranslationUnit or
clang_codeCompleteAt is called, a SourceManager is created with
UserFilesAreVolatile==false. This causes included files to be locked by mmap
after completion.

Experimenting with the default value for the UserFilesAreVolatile parameter to
true, I confirmed that after calling clang_reparseTranslationUnit and/or
clang_codeCompleteAt I can still save foo.hpp. However I have not thoroughly
investigated the implication of changes to other libclang functions.

** <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - Customize Bugzilla to have some LLVM flavah"
   href="show_bug.cgi?id=2">Bug #2</a>

The modifications in the last paragraph caused a different problem in code
completions.

While still keeping CXTranslationUnit generated for foo.cpp, I tried adding a
new property to class Foo and then saved foo.hpp. Subsequently trying to do
code completions in foo.cpp for methods and properties of class Foo
with clang_codeCompleteAt will result in non-nullptr valid value, but the
number of suggestions are in thousands. This is similar to case when one tries
to call code completions for global scope "::".

The symptom persists until the CXTranslationUnit for foo.cpp is discarded.
After discarding and regenerating CXTranslationUnit, a correct result was
returned. mmap was used for preamble-XXXX.pch in this situation. Maybe there is
some issue regarding creation/cleanup of preamble-XXXX.pch?

It should be noted that setting shouldUseMmap to always return false fixed BOTH
<a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - Need to add product version numbers"
   href="show_bug.cgi?id=1">Bug #1</a> (file lock issue) and <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - Customize Bugzilla to have some LLVM flavah"
   href="show_bug.cgi?id=2">Bug #2</a> (incorrect code completions). So I am
suspecting that both bug stem from mmap handling.

** Request for improvement

With the above in mind I would like to request a new feature.

System include files are flagged as IsSystemFile==true, causing mmap to be used
and the files to be locked. But this can be problematic if one is creating or
editing system library himself, but mmap has the header files locked.

Thus, I would think that it would be more appropriate if user can specifically
dictate the libclang's use of mmap, possibly as follows:

-Always : Suitable if not editing headers
-Default: Current implementation; when system header is not edited.
-Never  : If system header file needs to be edited

This will allow users to change setting per use cases.

Best Regards.</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>