Commit 69a39dc1 authored by Sam McCall's avatar Sam McCall
Browse files

[clangd] Increase stack size of the new threads on macOS

Summary: By default it's 512K, which is way to small for clang parser to run on. There is no way to do it via platform-independent API, so it's implemented via pthreads directly in clangd/Threading.cpp.

Fixes https://github.com/clangd/clangd/issues/273

Patch by Dmitry Kozhevnikov!

Reviewers: ilya-biryukov, sammccall, arphaman

Reviewed By: ilya-biryukov, sammccall, arphaman

Subscribers: dexonsmith, umanwizard, jfb, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D50993
parent 2a191cf8
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
#include "Threading.h"
#include "Trace.h"
#include "clang/Basic/Stack.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Threading.h"
@@ -86,16 +87,16 @@ void AsyncTaskRunner::runAsync(const llvm::Twine &Name,
    }
  });

  std::thread(
      [](std::string Name, decltype(Action) Action, decltype(CleanupTask)) {
  auto Task = [Name = Name.str(), Action = std::move(Action),
               Cleanup = std::move(CleanupTask)]() mutable {
    llvm::set_thread_name(Name);
    Action();
        // Make sure function stored by Action is destroyed before CleanupTask
        // is run.
    // Make sure function stored by ThreadFunc is destroyed before Cleanup runs.
    Action = nullptr;
      },
      Name.str(), std::move(Action), std::move(CleanupTask))
      .detach();
  };

  // Ensure our worker threads have big enough stacks to run clang.
  llvm::llvm_execute_on_thread_async(std::move(Task), clang::DesiredStackSize);
}

Deadline timeoutSeconds(llvm::Optional<double> Seconds) {
+21 −0
Original line number Diff line number Diff line
@@ -1065,6 +1065,27 @@ TEST_F(ClangdVFSTest, FallbackWhenWaitingForCompileCommand) {
                                Field(&CodeCompletion::Scope, "ns::"))));
}

TEST_F(ClangdVFSTest, TestStackOverflow) {
  MockFSProvider FS;
  ErrorCheckingCallbacks DiagConsumer;
  MockCompilationDatabase CDB;
  ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer);

  const char *SourceContents = R"cpp(
    constexpr int foo() { return foo(); }
    static_assert(foo());
  )cpp";

  auto FooCpp = testPath("foo.cpp");
  FS.Files[FooCpp] = SourceContents;

  Server.addDocument(FooCpp, SourceContents);
  ASSERT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics";
  // check that we got a constexpr depth error, and not crashed by stack
  // overflow
  EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
}

} // namespace
} // namespace clangd
} // namespace clang