|
58 | 58 | #include "support/Logger.h"
|
59 | 59 | #include "support/MemoryTree.h"
|
60 | 60 | #include "support/Path.h"
|
| 61 | +#include "support/ThreadCrashReporter.h" |
61 | 62 | #include "support/Threading.h"
|
62 | 63 | #include "support/Trace.h"
|
63 | 64 | #include "clang/Frontend/CompilerInvocation.h"
|
|
76 | 77 | #include "llvm/Support/FormatVariadic.h"
|
77 | 78 | #include "llvm/Support/Path.h"
|
78 | 79 | #include "llvm/Support/Threading.h"
|
| 80 | +#include "llvm/Support/raw_ostream.h" |
79 | 81 | #include <algorithm>
|
80 | 82 | #include <atomic>
|
81 | 83 | #include <chrono>
|
@@ -902,6 +904,40 @@ void ASTWorker::runWithAST(
|
902 | 904 | startTask(Name, std::move(Task), /*Update=*/None, Invalidation);
|
903 | 905 | }
|
904 | 906 |
|
| 907 | +/// To be called from ThreadCrashReporter's signal handler. |
| 908 | +static void crashDumpCompileCommand(llvm::raw_ostream &OS, |
| 909 | + const tooling::CompileCommand &Command) { |
| 910 | + OS << " Filename: " << Command.Filename << "\n"; |
| 911 | + OS << " Directory: " << Command.Directory << "\n"; |
| 912 | + OS << " Command Line:"; |
| 913 | + for (auto &Arg : Command.CommandLine) { |
| 914 | + OS << " " << Arg; |
| 915 | + } |
| 916 | + OS << "\n"; |
| 917 | +} |
| 918 | + |
| 919 | +/// To be called from ThreadCrashReporter's signal handler. |
| 920 | +static void crashDumpFileContents(llvm::raw_ostream &OS, |
| 921 | + const std::string &Contents) { |
| 922 | + // Avoid flooding the terminal with source code by default, but allow clients |
| 923 | + // to opt in. Use an env var to preserve backwards compatibility of the |
| 924 | + // command line interface, while allowing it to be set outside the clangd |
| 925 | + // launch site for more flexibility. |
| 926 | + if (getenv("CLANGD_CRASH_DUMP_SOURCE")) { |
| 927 | + OS << " Contents:\n"; |
| 928 | + OS << Contents << "\n"; |
| 929 | + } |
| 930 | +} |
| 931 | + |
| 932 | +/// To be called from ThreadCrashReporter's signal handler. |
| 933 | +static void crashDumpParseInputs(llvm::raw_ostream &OS, |
| 934 | + const ParseInputs &FileInputs) { |
| 935 | + auto &Command = FileInputs.CompileCommand; |
| 936 | + crashDumpCompileCommand(OS, Command); |
| 937 | + OS << " Version: " << FileInputs.Version << "\n"; |
| 938 | + crashDumpFileContents(OS, FileInputs.Contents); |
| 939 | +} |
| 940 | + |
905 | 941 | void PreambleThread::build(Request Req) {
|
906 | 942 | assert(Req.CI && "Got preamble request with null compiler invocation");
|
907 | 943 | const ParseInputs &Inputs = Req.Inputs;
|
@@ -932,6 +968,11 @@ void PreambleThread::build(Request Req) {
|
932 | 968 | FileName, Inputs.Version, LatestBuild->Version);
|
933 | 969 | }
|
934 | 970 |
|
| 971 | + ThreadCrashReporter ScopedReporter([&Inputs]() { |
| 972 | + llvm::errs() << "Signalled while building preamble\n"; |
| 973 | + crashDumpParseInputs(llvm::errs(), Inputs); |
| 974 | + }); |
| 975 | + |
935 | 976 | LatestBuild = clang::clangd::buildPreamble(
|
936 | 977 | FileName, *Req.CI, Inputs, StoreInMemory,
|
937 | 978 | [this, Version(Inputs.Version)](ASTContext &Ctx,
|
@@ -1288,6 +1329,11 @@ void ASTWorker::run() {
|
1288 | 1329 | Status.ASTActivity.Name = CurrentRequest->Name;
|
1289 | 1330 | });
|
1290 | 1331 | WithContext WithProvidedContext(ContextProvider(FileName));
|
| 1332 | + ThreadCrashReporter ScopedReporter([this]() { |
| 1333 | + const char *Name = CurrentRequest ? CurrentRequest->Name.c_str() : ""; |
| 1334 | + llvm::errs() << "Signalled during AST worker action: " << Name << "\n"; |
| 1335 | + crashDumpParseInputs(llvm::errs(), FileInputs); |
| 1336 | + }); |
1291 | 1337 | CurrentRequest->Action();
|
1292 | 1338 | }
|
1293 | 1339 |
|
@@ -1613,6 +1659,11 @@ void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
|
1613 | 1659 | Ctx = Context::current().derive(kFileBeingProcessed,
|
1614 | 1660 | std::string(File)),
|
1615 | 1661 | Action = std::move(Action), this]() mutable {
|
| 1662 | + ThreadCrashReporter ScopedReporter([&Name, &Contents, &Command]() { |
| 1663 | + llvm::errs() << "Signalled during preamble action: " << Name << "\n"; |
| 1664 | + crashDumpCompileCommand(llvm::errs(), Command); |
| 1665 | + crashDumpFileContents(llvm::errs(), Contents); |
| 1666 | + }); |
1616 | 1667 | std::shared_ptr<const PreambleData> Preamble;
|
1617 | 1668 | if (Consistency == PreambleConsistency::Stale) {
|
1618 | 1669 | // Wait until the preamble is built for the first time, if preamble
|
|
0 commit comments