45
45
46
46
#include " CompilationRecord.h"
47
47
48
+ #include < signal.h>
49
+
48
50
#define DEBUG_TYPE " batch-mode"
49
51
50
52
// Batch-mode has a sub-mode for testing that randomizes batch partitions,
@@ -458,6 +460,35 @@ namespace driver {
458
460
}
459
461
}
460
462
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
+
461
492
// / Unpack a \c BatchJob that has finished into its constituent \c Job
462
493
// / members, and call \c taskFinished on each, propagating any \c
463
494
// / TaskFinishedResponse other than \c
@@ -483,6 +514,27 @@ namespace driver {
483
514
return res;
484
515
}
485
516
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
+
486
538
// / Callback which will be called immediately after a task has finished
487
539
// / execution. Determines if execution should continue, and also schedule
488
540
// / any additional Jobs which we now know we need to run.
@@ -510,12 +562,8 @@ namespace driver {
510
562
llvm::errs () << Output;
511
563
break ;
512
564
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);
519
567
break ;
520
568
}
521
569
}
0 commit comments