Skip to content

Commit 84540c0

Browse files
committed
[BatchMode] <rdar://40526328> Emit signalled message (SIGINT) for batch constituents cancelled due to errors elsewhere.
1 parent 07f6e36 commit 84540c0

File tree

1 file changed

+53
-6
lines changed

1 file changed

+53
-6
lines changed

lib/Driver/Compilation.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545

4646
#include "CompilationRecord.h"
4747

48+
#include <signal.h>
49+
4850
#define DEBUG_TYPE "batch-mode"
4951

5052
// Batch-mode has a sub-mode for testing that randomizes batch partitions,
@@ -459,6 +461,35 @@ namespace driver {
459461
}
460462
}
461463

464+
/// Check to see if a job produced a zero-length serialized diagnostics
465+
/// file, which is used to indicate batch-constituents that were batched
466+
/// together with a failing constituent but did not, themselves, produce any
467+
/// errors.
468+
bool jobWasBatchedWithFailingJobs(const Job *J) const {
469+
auto DiaPath =
470+
J->getOutput().getAnyOutputForType(file_types::TY_SerializedDiagnostics);
471+
if (DiaPath.empty())
472+
return false;
473+
if (!llvm::sys::fs::is_regular_file(DiaPath))
474+
return false;
475+
uint64_t Size;
476+
auto EC = llvm::sys::fs::file_size(DiaPath, Size);
477+
if (EC)
478+
return false;
479+
return Size == 0;
480+
}
481+
482+
/// If a batch-constituent job happens to be batched together with a job
483+
/// that exits with an error, the batch-constituent may be considered
484+
/// "cancelled".
485+
bool jobIsCancelledBatchConstituent(int ReturnCode,
486+
const Job *ContainerJob,
487+
const Job *ConstituentJob) {
488+
return ReturnCode != 0 &&
489+
isBatchJob(ContainerJob) &&
490+
jobWasBatchedWithFailingJobs(ConstituentJob);
491+
}
492+
462493
/// Unpack a \c BatchJob that has finished into its constituent \c Job
463494
/// members, and call \c taskFinished on each, propagating any \c
464495
/// TaskFinishedResponse other than \c
@@ -482,6 +513,26 @@ namespace driver {
482513
return res;
483514
}
484515

516+
void
517+
emitParseableOutputForEachFinishedJob(ProcessId Pid, int ReturnCode,
518+
StringRef Output,
519+
const Job *FinishedCmd) {
520+
FinishedCmd->forEachContainedJobAndPID(Pid, [&](const Job *J,
521+
Job::PID P) {
522+
if (jobIsCancelledBatchConstituent(ReturnCode, FinishedCmd, J)) {
523+
// Simulate SIGINT-interruption to parseable-output consumer for any
524+
// constituent of a failing batch job that produced no errors of its
525+
// own.
526+
parseable_output::emitSignalledMessage(llvm::errs(), *J, P,
527+
"cancelled batch constituent",
528+
"", SIGINT);
529+
} else {
530+
parseable_output::emitFinishedMessage(llvm::errs(), *J, P, ReturnCode,
531+
Output);
532+
}
533+
});
534+
}
535+
485536
/// Callback which will be called immediately after a task has finished
486537
/// execution. Determines if execution should continue, and also schedule
487538
/// any additional Jobs which we now know we need to run.
@@ -508,12 +559,8 @@ namespace driver {
508559
llvm::errs() << Output;
509560
break;
510561
case OutputLevel::Parseable:
511-
// Parseable output was requested.
512-
FinishedCmd->forEachContainedJobAndPID(
513-
Pid, [&](const Job *J, Job::PID P) {
514-
parseable_output::emitFinishedMessage(llvm::errs(), *J, P,
515-
ReturnCode, Output);
516-
});
562+
emitParseableOutputForEachFinishedJob(Pid, ReturnCode, Output,
563+
FinishedCmd);
517564
break;
518565
}
519566
}

0 commit comments

Comments
 (0)