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,
@@ -459,6 +461,35 @@ namespace driver {
459
461
}
460
462
}
461
463
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
+
462
493
// / Unpack a \c BatchJob that has finished into its constituent \c Job
463
494
// / members, and call \c taskFinished on each, propagating any \c
464
495
// / TaskFinishedResponse other than \c
@@ -482,6 +513,26 @@ namespace driver {
482
513
return res;
483
514
}
484
515
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
+
485
536
// / Callback which will be called immediately after a task has finished
486
537
// / execution. Determines if execution should continue, and also schedule
487
538
// / any additional Jobs which we now know we need to run.
@@ -508,12 +559,8 @@ namespace driver {
508
559
llvm::errs () << Output;
509
560
break ;
510
561
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);
517
564
break ;
518
565
}
519
566
}
0 commit comments