Skip to content

Commit 0bbdf73

Browse files
authored
Merge pull request #11001 from cachemeifyoucan/eng/PR-daemon-cas-recovery-release
[6.2][CAS] Delay CAS initialization on server side after daemon starts
2 parents b6943cf + 861fcbd commit 0bbdf73

File tree

3 files changed

+84
-64
lines changed

3 files changed

+84
-64
lines changed

clang/test/CAS/daemon-cas-recovery.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// REQUIRES: system-darwin, clang-cc1daemon
2+
3+
// RUN: rm -rf %t && mkdir -p %t
4+
5+
/// Construct a malformed CAS to recovery from.
6+
// RUN: echo "abc" | llvm-cas --cas %t/cas --make-blob --data -
7+
// RUN: rm %t/cas/v1.1/v9.data
8+
// RUN: not llvm-cas --cas %t/cas --validate --check-hash
9+
10+
// RUN: env LLVM_CACHE_CAS_PATH=%t/cas LLVM_CAS_FORCE_VALIDATION=1 %clang-cache \
11+
// RUN: %clang -fsyntax-only -x c %s
12+
13+
int func(void);

clang/test/CAS/depscan-cas-log.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
// CHECK: [[PID1:[0-9]*]] {{[0-9]*}}: mmap '{{.*}}v9.index'
1414
// CHECK: [[PID1]] {{[0-9]*}}: create subtrie
1515

16-
// CHECK: [[PID2:[0-9]*]] {{[0-9]*}}: mmap '{{.*}}v9.index'
1716
// Even a minimal compilation involves at least 9 records for the cache key.
18-
// CHECK-COUNT-9: [[PID2]] {{[0-9]*}}: create record
17+
// CHECK-COUNT-9: [[PID1]] {{[0-9]*}}: create record
1918

20-
// CHECK: [[PID1]] {{[0-9]*}}: close mmap '{{.*}}v9.index'
19+
// CHECK: [[PID2:[0-9]*]] {{[0-9]*}}: mmap '{{.*}}v9.index'
20+
// CHECK: [[PID2]] {{[0-9]*}}: close mmap '{{.*}}v9.index'

clang/tools/driver/cc1depscan_main.cpp

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -357,13 +357,14 @@ makeDepscanDaemonPath(StringRef Mode, const DepscanSharing &Sharing) {
357357
return std::nullopt;
358358
}
359359

360-
static Expected<llvm::cas::CASID> scanAndUpdateCC1Inline(
361-
const char *Exec, ArrayRef<const char *> InputArgs,
362-
StringRef WorkingDirectory, SmallVectorImpl<const char *> &OutputArgs,
363-
bool ProduceIncludeTree, bool &DiagnosticErrorOccurred,
364-
llvm::function_ref<const char *(const Twine &)> SaveArg,
365-
const CASOptions &CASOpts, std::shared_ptr<llvm::cas::ObjectStore> DB,
366-
std::shared_ptr<llvm::cas::ActionCache> Cache);
360+
static int
361+
scanAndUpdateCC1Inline(const char *Exec, ArrayRef<const char *> InputArgs,
362+
StringRef WorkingDirectory,
363+
SmallVectorImpl<const char *> &OutputArgs,
364+
bool ProduceIncludeTree,
365+
llvm::function_ref<const char *(const Twine &)> SaveArg,
366+
const CASOptions &CASOpts, DiagnosticsEngine &Diag,
367+
std::optional<llvm::cas::CASID> &RootID);
367368

368369
static Expected<llvm::cas::CASID> scanAndUpdateCC1InlineWithTool(
369370
tooling::dependencies::DependencyScanningTool &Tool,
@@ -372,14 +373,17 @@ static Expected<llvm::cas::CASID> scanAndUpdateCC1InlineWithTool(
372373
SmallVectorImpl<const char *> &OutputArgs, llvm::cas::ObjectStore &DB,
373374
llvm::function_ref<const char *(const Twine &)> SaveArg);
374375

375-
static llvm::Expected<llvm::cas::CASID> scanAndUpdateCC1UsingDaemon(
376+
static int scanAndUpdateCC1UsingDaemon(
376377
const char *Exec, ArrayRef<const char *> OldArgs,
377378
StringRef WorkingDirectory, SmallVectorImpl<const char *> &NewArgs,
378-
std::string &DiagnosticOutput, StringRef Path,
379-
const DepscanSharing &Sharing,
379+
StringRef Path, const DepscanSharing &Sharing, DiagnosticsEngine &Diag,
380380
llvm::function_ref<const char *(const Twine &)> SaveArg,
381-
llvm::cas::ObjectStore &CAS) {
381+
const CASOptions &CASOpts, std::optional<llvm::cas::CASID> &Root) {
382382
using namespace clang::cc1depscand;
383+
auto reportScanFailure = [&](Error E) {
384+
Diag.Report(diag::err_cas_depscan_failed) << std::move(E);
385+
return 1;
386+
};
383387

384388
// FIXME: Skip some of this if -fcas-fs has been passed.
385389

@@ -389,12 +393,12 @@ static llvm::Expected<llvm::cas::CASID> scanAndUpdateCC1UsingDaemon(
389393
? ScanDaemon::connectToDaemonAndShakeHands(Path)
390394
: ScanDaemon::constructAndShakeHands(Path, Exec, Sharing);
391395
if (!Daemon)
392-
return Daemon.takeError();
396+
return reportScanFailure(Daemon.takeError());
393397
CC1DepScanDProtocol Comms(*Daemon);
394398

395399
// llvm::dbgs() << "sending request...\n";
396400
if (auto E = Comms.putCommand(WorkingDirectory, OldArgs))
397-
return std::move(E);
401+
return reportScanFailure(std::move(E));
398402

399403
llvm::BumpPtrAllocator Alloc;
400404
llvm::StringSaver Saver(Alloc);
@@ -403,23 +407,32 @@ static llvm::Expected<llvm::cas::CASID> scanAndUpdateCC1UsingDaemon(
403407
StringRef FailedReason;
404408
StringRef RootID;
405409
StringRef DiagOut;
406-
if (auto E = Comms.getScanResult(Saver, Result, FailedReason, RootID,
407-
RawNewArgs, DiagOut)) {
408-
DiagnosticOutput = DiagOut;
409-
return std::move(E);
410-
}
411-
DiagnosticOutput = DiagOut;
410+
auto E = Comms.getScanResult(Saver, Result, FailedReason, RootID, RawNewArgs,
411+
DiagOut);
412+
// Send the diagnostics to std::err.
413+
llvm::errs() << DiagOut;
414+
if (E)
415+
return reportScanFailure(std::move(E));
412416

413417
if (Result != CC1DepScanDProtocol::SuccessResult)
414-
return llvm::createStringError(llvm::inconvertibleErrorCode(),
415-
"depscan daemon failed: " + FailedReason);
418+
return reportScanFailure(
419+
llvm::createStringError("depscan daemon failed: " + FailedReason));
416420

417421
// FIXME: Avoid this duplication.
418422
NewArgs.resize(RawNewArgs.size());
419423
for (int I = 0, E = RawNewArgs.size(); I != E; ++I)
420424
NewArgs[I] = SaveArg(RawNewArgs[I]);
421425

422-
return CAS.parseID(RootID);
426+
// Create CAS after daemon returns the result so daemon can perform corrupted
427+
// CAS recovery.
428+
auto [CAS, _] = CASOpts.getOrCreateDatabases(Diag);
429+
if (!CAS)
430+
return 1;
431+
432+
if (auto E = CAS->parseID(RootID).moveInto(Root))
433+
return reportScanFailure(std::move(E));
434+
435+
return 0;
423436
}
424437

425438
// FIXME: This is a copy of Command::writeResponseFile. Command is too deeply
@@ -446,8 +459,6 @@ static int scanAndUpdateCC1(const char *Exec, ArrayRef<const char *> OldArgs,
446459
DiagnosticsEngine &Diag,
447460
const llvm::opt::ArgList &Args,
448461
const CASOptions &CASOpts,
449-
std::shared_ptr<llvm::cas::ObjectStore> DB,
450-
std::shared_ptr<llvm::cas::ActionCache> Cache,
451462
std::optional<llvm::cas::CASID> &RootID) {
452463
using namespace clang::driver;
453464

@@ -513,25 +524,14 @@ static int scanAndUpdateCC1(const char *Exec, ArrayRef<const char *> OldArgs,
513524
if (ProduceIncludeTree)
514525
Sharing.CASArgs.push_back("-fdepscan-include-tree");
515526

516-
std::string DiagnosticOutput;
517-
bool DiagnosticErrorOccurred = false;
518-
auto ScanAndUpdate = [&]() {
519-
if (std::optional<std::string> DaemonPath =
520-
makeDepscanDaemonPath(Mode, Sharing))
521-
return scanAndUpdateCC1UsingDaemon(Exec, OldArgs, WorkingDirectory,
522-
NewArgs, DiagnosticOutput, *DaemonPath,
523-
Sharing, SaveArg, *DB);
524-
return scanAndUpdateCC1Inline(Exec, OldArgs, WorkingDirectory, NewArgs,
525-
ProduceIncludeTree, DiagnosticErrorOccurred,
526-
SaveArg, CASOpts, DB, Cache);
527-
};
528-
if (llvm::Error E = ScanAndUpdate().moveInto(RootID)) {
529-
Diag.Report(diag::err_cas_depscan_failed) << std::move(E);
530-
if (!DiagnosticOutput.empty())
531-
llvm::errs() << DiagnosticOutput;
532-
return 1;
533-
}
534-
return DiagnosticErrorOccurred;
527+
if (auto DaemonPath = makeDepscanDaemonPath(Mode, Sharing))
528+
return scanAndUpdateCC1UsingDaemon(Exec, OldArgs, WorkingDirectory, NewArgs,
529+
*DaemonPath, Sharing, Diag, SaveArg,
530+
CASOpts, RootID);
531+
532+
return scanAndUpdateCC1Inline(Exec, OldArgs, WorkingDirectory, NewArgs,
533+
ProduceIncludeTree, SaveArg, CASOpts, Diag,
534+
RootID);
535535
}
536536

537537
int cc1depscan_main(ArrayRef<const char *> Argv, const char *Argv0,
@@ -591,12 +591,8 @@ int cc1depscan_main(ArrayRef<const char *> Argv, const char *Argv0,
591591
CompilerInvocation::ParseCASArgs(CASOpts, ParsedCC1Args, Diags);
592592
CASOpts.ensurePersistentCAS();
593593

594-
auto [CAS, Cache] = CASOpts.getOrCreateDatabases(Diags);
595-
if (!CAS || !Cache)
596-
return 1;
597-
598594
if (int Ret = scanAndUpdateCC1(Argv0, CC1Args->getValues(), NewArgs, Diags,
599-
Args, CASOpts, CAS, Cache, RootID))
595+
Args, CASOpts, RootID))
600596
return Ret;
601597

602598
// FIXME: Use OutputBackend to OnDisk only now.
@@ -841,7 +837,8 @@ void ScanServer::start(bool Exclusive, ArrayRef<const char *> CASArgs) {
841837
ExitOnErr(llvm::cas::validateOnDiskUnifiedCASDatabasesIfNeeded(
842838
CASPath, /*CheckHash=*/true,
843839
/*AllowRecovery=*/true,
844-
/*Force=*/false, findLLVMCasBinary(Argv0, LLVMCasStorage)));
840+
/*Force=*/getenv("LLVM_CAS_FORCE_VALIDATION"),
841+
findLLVMCasBinary(Argv0, LLVMCasStorage)));
845842
});
846843

847844
// Check the pidfile.
@@ -1106,13 +1103,18 @@ static Expected<llvm::cas::CASID> scanAndUpdateCC1InlineWithTool(
11061103
return *Root;
11071104
}
11081105

1109-
static Expected<llvm::cas::CASID> scanAndUpdateCC1Inline(
1110-
const char *Exec, ArrayRef<const char *> InputArgs,
1111-
StringRef WorkingDirectory, SmallVectorImpl<const char *> &OutputArgs,
1112-
bool ProduceIncludeTree, bool &DiagnosticErrorOccurred,
1113-
llvm::function_ref<const char *(const Twine &)> SaveArg,
1114-
const CASOptions &CASOpts, std::shared_ptr<llvm::cas::ObjectStore> DB,
1115-
std::shared_ptr<llvm::cas::ActionCache> Cache) {
1106+
static int
1107+
scanAndUpdateCC1Inline(const char *Exec, ArrayRef<const char *> InputArgs,
1108+
StringRef WorkingDirectory,
1109+
SmallVectorImpl<const char *> &OutputArgs,
1110+
bool ProduceIncludeTree,
1111+
llvm::function_ref<const char *(const Twine &)> SaveArg,
1112+
const CASOptions &CASOpts, DiagnosticsEngine &Diag,
1113+
std::optional<llvm::cas::CASID> &RootID) {
1114+
auto [DB, Cache] = CASOpts.getOrCreateDatabases(Diag);
1115+
if (!DB || !Cache)
1116+
return 1;
1117+
11161118
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> FS;
11171119
if (!ProduceIncludeTree)
11181120
FS = llvm::cantFail(llvm::cas::createCachingOnDiskFileSystem(*DB));
@@ -1136,10 +1138,15 @@ static Expected<llvm::cas::CASID> scanAndUpdateCC1Inline(
11361138
auto DiagsConsumer = std::make_unique<TextDiagnosticPrinter>(
11371139
llvm::errs(), DiagOpts.get(), false);
11381140

1139-
auto Result = scanAndUpdateCC1InlineWithTool(
1140-
Tool, *DiagsConsumer, /*VerboseOS*/ nullptr, Exec, InputArgs,
1141-
WorkingDirectory, OutputArgs, *DB, SaveArg);
1142-
DiagnosticErrorOccurred = DiagsConsumer->getNumErrors() != 0;
1143-
return Result;
1141+
auto E = scanAndUpdateCC1InlineWithTool(
1142+
Tool, *DiagsConsumer, /*VerboseOS*/ nullptr, Exec, InputArgs,
1143+
WorkingDirectory, OutputArgs, *DB, SaveArg)
1144+
.moveInto(RootID);
1145+
if (E) {
1146+
Diag.Report(diag::err_cas_depscan_failed) << std::move(E);
1147+
return 1;
1148+
}
1149+
1150+
return DiagsConsumer->getNumErrors() != 0;
11441151
}
11451152
#endif /* LLVM_ON_UNIX */

0 commit comments

Comments
 (0)