From d4871207ed44c8e5edf0961ae7736c24075486ba Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 28 Sep 2018 13:41:50 -0700 Subject: [PATCH] Construct SourceManager with UserFilesAreVolatile Prettify pipeline --- src/clang_complete.cc | 6 ++++++ src/pipeline.cc | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index d5efae38..6a785470 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -202,6 +202,12 @@ std::unique_ptr BuildCompilerInstance( Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) return nullptr; + // Construct SourceManager with UserFilesAreVolatile: true because otherwise + // RequiresNullTerminator: true may cause out-of-bounds read when a file is + // mmap'ed but is saved concurrently. + Clang->createFileManager(); + Clang->setSourceManager(new SourceManager(Clang->getDiagnostics(), + Clang->getFileManager(), true)); return Clang; } diff --git a/src/pipeline.cc b/src/pipeline.cc index 59101324..ed01feeb 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -162,10 +162,14 @@ std::unique_ptr RawCacheLoad(const std::string &path) { IndexFile::kMajorVersion); } -bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, - Project *project, VFS *vfs, const GroupMatch &matcher) { +std::mutex &GetFileMutex(const std::string &path) { const int N_MUTEXES = 256; static std::mutex mutexes[N_MUTEXES]; + return mutexes[std::hash()(path) % N_MUTEXES]; +} + +bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, + Project *project, VFS *vfs, const GroupMatch &matcher) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; @@ -216,8 +220,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, if (reparse < 2) do { - std::unique_lock lock( - mutexes[std::hash()(path_to_index) % N_MUTEXES]); + std::unique_lock lock(GetFileMutex(path_to_index)); prev = RawCacheLoad(path_to_index); if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args, std::nullopt)) @@ -256,8 +259,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, std::string path = dep.first.val().str(); if (!vfs->Stamp(path, dep.second, 1)) continue; - std::lock_guard lock1( - mutexes[std::hash()(path) % N_MUTEXES]); + std::lock_guard lock1(GetFileMutex(path)); prev = RawCacheLoad(path); if (!prev) continue; @@ -313,7 +315,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles, LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev << ")"; { - std::lock_guard lock(mutexes[std::hash()(path) % N_MUTEXES]); + std::lock_guard lock(GetFileMutex(path)); if (vfs->Loaded(path)) prev = RawCacheLoad(path); else