Skip to content

Commit b28b38a

Browse files
sam-mccallzmodem
authored andcommitted
[clangd] Don't mmap source files on all platforms --> don't crash on git checkout
Summary: Previously we mmapped on unix and not on windows: on windows mmap takes an exclusive lock on the file and prevents the user saving changes! The failure mode on linux is a bit more subtle: if the file is changed on disk but the SourceManager sticks around, then subsequent operations on the SourceManager will fail as invariants are violated (e.g. null-termination). This commonly manifests as crashes after switching git branches with many files open in clangd. Nominally mmap is for performance here, and we should be willing to give some up to stop crashing. Measurements on my system (linux+desktop+SSD) at least show no measurable regression on an a fairly IO-heavy workload: drop disk caches, open SemaOverload.cpp, wait for first diagnostics. for i in `seq 100`; do for variant in mmap volatile; do echo 3 | sudo tee /proc/sys/vm/drop_caches /usr/bin/time --append --quiet -o ~/timings -f "%C %E" \ bin/clangd.$variant -sync -background-index=0 < /tmp/mirror > /dev/null done done bin/clangd.mmap -sync -background-index=0 0:07.60 bin/clangd.volatile -sync -background-index=0 0:07.89 bin/clangd.mmap -sync -background-index=0 0:07.44 bin/clangd.volatile -sync -background-index=0 0:07.89 bin/clangd.mmap -sync -background-index=0 0:07.42 bin/clangd.volatile -sync -background-index=0 0:07.50 bin/clangd.mmap -sync -background-index=0 0:07.90 bin/clangd.volatile -sync -background-index=0 0:07.53 bin/clangd.mmap -sync -background-index=0 0:07.64 bin/clangd.volatile -sync -background-index=0 0:07.55 bin/clangd.mmap -sync -background-index=0 0:07.75 bin/clangd.volatile -sync -background-index=0 0:07.47 bin/clangd.mmap -sync -background-index=0 0:07.90 bin/clangd.volatile -sync -background-index=0 0:07.50 bin/clangd.mmap -sync -background-index=0 0:07.81 bin/clangd.volatile -sync -background-index=0 0:07.95 bin/clangd.mmap -sync -background-index=0 0:07.55 bin/clangd.volatile -sync -background-index=0 0:07.65 bin/clangd.mmap -sync -background-index=0 0:08.15 bin/clangd.volatile -sync -background-index=0 0:07.54 bin/clangd.mmap -sync -background-index=0 0:07.78 bin/clangd.volatile -sync -background-index=0 0:07.61 bin/clangd.mmap -sync -background-index=0 0:07.78 bin/clangd.volatile -sync -background-index=0 0:07.55 bin/clangd.mmap -sync -background-index=0 0:07.41 bin/clangd.volatile -sync -background-index=0 0:07.40 bin/clangd.mmap -sync -background-index=0 0:07.54 bin/clangd.volatile -sync -background-index=0 0:07.42 bin/clangd.mmap -sync -background-index=0 0:07.45 bin/clangd.volatile -sync -background-index=0 0:07.49 bin/clangd.mmap -sync -background-index=0 0:07.95 bin/clangd.volatile -sync -background-index=0 0:07.66 bin/clangd.mmap -sync -background-index=0 0:08.04 Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73617 (cherry picked from commit b500c49)
1 parent b0536b5 commit b28b38a

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

clang-tools-extra/clangd/FSProvider.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ namespace clangd {
1919

2020
namespace {
2121
/// Always opens files in the underlying filesystem as "volatile", meaning they
22-
/// won't be memory-mapped. This avoid locking the files on Windows.
22+
/// won't be memory-mapped. Memory-mapping isn't desirable for clangd:
23+
/// - edits to the underlying files change contents MemoryBuffers owned by
24+
// SourceManager, breaking its invariants and leading to crashes
25+
/// - it locks files on windows, preventing edits
2326
class VolatileFileSystem : public llvm::vfs::ProxyFileSystem {
2427
public:
2528
explicit VolatileFileSystem(llvm::IntrusiveRefCntPtr FS)
@@ -34,7 +37,7 @@ class VolatileFileSystem : public llvm::vfs::ProxyFileSystem {
3437
if (!File)
3538
return File;
3639
// Try to guess preamble files, they can be memory-mapped even on Windows as
37-
// clangd has exclusive access to those.
40+
// clangd has exclusive access to those and nothing else should touch them.
3841
llvm::StringRef FileName = llvm::sys::path::filename(Path);
3942
if (FileName.startswith("preamble-") && FileName.endswith(".pch"))
4043
return File;
@@ -70,15 +73,11 @@ class VolatileFileSystem : public llvm::vfs::ProxyFileSystem {
7073

7174
llvm::IntrusiveRefCntPtr
7275
clang::clangd::RealFileSystemProvider::getFileSystem() const {
73-
// Avoid using memory-mapped files on Windows, they cause file locking issues.
74-
// FIXME: Try to use a similar approach in Sema instead of relying on
75-
// propagation of the 'isVolatile' flag through all layers.
76-
#ifdef _WIN32
76+
// Avoid using memory-mapped files.
77+
// FIXME: Try to use a similar approach in Sema instead of relying on
78+
// propagation of the 'isVolatile' flag through all layers.
7779
return new VolatileFileSystem(
7880
llvm::vfs::createPhysicalFileSystem().release());
79-
#else
80-
return llvm::vfs::createPhysicalFileSystem().release();
81-
#endif
8281
}
8382
} // namespace clangd
8483
} // namespace clang

clang-tools-extra/clangd/FSProvider.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class FileSystemProvider {
3030

3131
class RealFileSystemProvider : public FileSystemProvider {
3232
public:
33-
// FIXME: returns the single real FS instance, which is not threadsafe.
3433
llvm::IntrusiveRefCntPtr
3534
getFileSystem() const override;
3635
};

0 commit comments

Comments
 (0)