r341910 - [Tooling] Restore working dir in ClangTool.

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 11 00:29:10 PDT 2018


Author: ibiryukov
Date: Tue Sep 11 00:29:09 2018
New Revision: 341910

URL: http://llvm.org/viewvc/llvm-project?rev=341910&view=rev
Log:
[Tooling] Restore working dir in ClangTool.

Summary:
And add an option to disable this behavior. The option is only used in
AllTUsExecutor to avoid races when running concurrently on multiple
threads.

This fixes PR38869 introduced by r340937.

Reviewers: ioeric, steveire

Reviewed By: ioeric

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D51864

Modified:
    cfe/trunk/include/clang/Tooling/Tooling.h
    cfe/trunk/lib/Tooling/AllTUsExecution.cpp
    cfe/trunk/lib/Tooling/Tooling.cpp

Modified: cfe/trunk/include/clang/Tooling/Tooling.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=341910&r1=341909&r2=341910&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Tooling.h (original)
+++ cfe/trunk/include/clang/Tooling/Tooling.h Tue Sep 11 00:29:09 2018
@@ -356,6 +356,11 @@ public:
   /// append them to ASTs.
   int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
 
+  /// Sets whether working directory should be restored after calling run(). By
+  /// default, working directory is restored. However, it could be useful to
+  /// turn this off when running on multiple threads to avoid the raciness.
+  void setRestoreWorkingDir(bool RestoreCWD);
+
   /// Returns the file manager used in the tool.
   ///
   /// The file manager is shared between all translation units.
@@ -380,6 +385,8 @@ private:
   ArgumentsAdjuster ArgsAdjuster;
 
   DiagnosticConsumer *DiagConsumer = nullptr;
+
+  bool RestoreCWD = true;
 };
 
 template <typename T>

Modified: cfe/trunk/lib/Tooling/AllTUsExecution.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/AllTUsExecution.cpp?rev=341910&r1=341909&r2=341910&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/AllTUsExecution.cpp (original)
+++ cfe/trunk/lib/Tooling/AllTUsExecution.cpp Tue Sep 11 00:29:09 2018
@@ -104,7 +104,12 @@ llvm::Error AllTUsToolExecutor::execute(
   {
     llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
                                            : ThreadCount);
-
+    llvm::SmallString<128> InitialWorkingDir;
+    if (auto EC = llvm::sys::fs::current_path(InitialWorkingDir)) {
+      InitialWorkingDir = "";
+      llvm::errs() << "Error while getting current working directory: "
+                   << EC.message() << "\n";
+    }
     for (std::string File : Files) {
       Pool.async(
           [&](std::string Path) {
@@ -116,12 +121,19 @@ llvm::Error AllTUsToolExecutor::execute(
             for (const auto &FileAndContent : OverlayFiles)
               Tool.mapVirtualFile(FileAndContent.first(),
                                   FileAndContent.second);
+            // Do not restore working dir from multiple threads to avoid races.
+            Tool.setRestoreWorkingDir(false);
             if (Tool.run(Action.first.get()))
               AppendError(llvm::Twine("Failed to run action on ") + Path +
                           "\n");
           },
           File);
     }
+    if (!InitialWorkingDir.empty()) {
+      if (auto EC = llvm::sys::fs::set_current_path(InitialWorkingDir))
+        llvm::errs() << "Error while restoring working directory: "
+                     << EC.message() << "\n";
+    }
   }
 
   if (!ErrorMsg.empty())

Modified: cfe/trunk/lib/Tooling/Tooling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=341910&r1=341909&r2=341910&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Tooling.cpp (original)
+++ cfe/trunk/lib/Tooling/Tooling.cpp Tue Sep 11 00:29:09 2018
@@ -441,6 +441,17 @@ int ClangTool::run(ToolAction *Action) {
     AbsolutePaths.push_back(std::move(*AbsPath));
   }
 
+  // Remember the working directory in case we need to restore it.
+  std::string InitialWorkingDir;
+  if (RestoreCWD) {
+    if (auto CWD = OverlayFileSystem->getCurrentWorkingDirectory()) {
+      InitialWorkingDir = std::move(*CWD);
+    } else {
+      llvm::errs() << "Could not get working directory: "
+                   << CWD.getError().message() << "\n";
+    }
+  }
+
   for (llvm::StringRef File : AbsolutePaths) {
     // Currently implementations of CompilationDatabase::getCompileCommands can
     // change the state of the file system (e.g.  prepare generated headers), so
@@ -508,6 +519,13 @@ int ClangTool::run(ToolAction *Action) {
       }
     }
   }
+
+  if (!InitialWorkingDir.empty()) {
+    if (auto EC =
+            OverlayFileSystem->setCurrentWorkingDirectory(InitialWorkingDir))
+      llvm::errs() << "Error when trying to restore working dir: "
+                   << EC.message() << "\n";
+  }
   return ProcessingFailed ? 1 : (FileSkipped ? 2 : 0);
 }
 
@@ -544,6 +562,10 @@ int ClangTool::buildASTs(std::vector<std
   return run(&Action);
 }
 
+void ClangTool::setRestoreWorkingDir(bool RestoreCWD) {
+  this->RestoreCWD = RestoreCWD;
+}
+
 namespace clang {
 namespace tooling {
 




More information about the cfe-commits mailing list