Skip to content

Commit dcc4373

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

File tree

1 file changed

+54
-6
lines changed

1 file changed

+54
-6
lines changed

lib/Driver/Compilation.cpp

Lines changed: 54 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,
@@ -458,6 +460,35 @@ namespace driver {
458460
}
459461
}
460462

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

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

0 commit comments

Comments
 (0)