@@ -420,6 +420,7 @@ public final class SwiftDriverJobTaskAction: TaskAction, BuildValueValidatingTas
420420 private var pid = llbuild_pid_t. invalid
421421
422422 var executionError : String ?
423+ var wasSignaled : Bool = false
423424 private var processStarted = false
424425 private var _commandResult : CommandResult ?
425426 var commandResult : CommandResult ? {
@@ -469,10 +470,15 @@ public final class SwiftDriverJobTaskAction: TaskAction, BuildValueValidatingTas
469470 }
470471
471472 func processFinished( result: CommandExtendedResult ) {
473+ if wasSignaled {
474+ // If the process was already signaled, this might be in a reproducer creation. No need to update finish status.
475+ return
476+ }
472477 guard let status = Processes . ExitStatus. init ( rawValue: result. exitStatus) else {
473478 // nil means the job is stopped or continued. It should not call finished.
474479 return
475480 }
481+ wasSignaled = status. wasSignaled
476482 // This may be updated by commandStarted in the case of certain failures,
477483 // so only update the exit status in output delegate if it is nil.
478484 if outputDelegate. result == nil {
@@ -526,6 +532,21 @@ public final class SwiftDriverJobTaskAction: TaskAction, BuildValueValidatingTas
526532
527533 try await spawn( commandLine: options. commandLine, environment: environment, workingDirectory: task. workingDirectory, dynamicExecutionDelegate: dynamicExecutionDelegate, clientDelegate: clientDelegate, processDelegate: delegate)
528534
535+ // Generate crash reproducoer.
536+ if delegate. wasSignaled {
537+ // The output directory for crash reproducer is:
538+ // * Specified by environment
539+ // * Primary output path directory
540+ // * Temp directory
541+ let reproDir = environment [ " SWIFT_CRASH_DIAGNOSTICS_DIR " ] . map ( Path . init) ?? driverJob. driverJob. outputs. first? . dirname
542+ try await withTemporaryDirectory ( dir: reproDir, prefix: " swift-crash-reproducer " , removeTreeOnDeinit: false ) { dir in
543+ if let reproCommand = try await plannedBuild? . getCrashReproducerCommand ( for: driverJob, output: dir) {
544+ try await spawn ( commandLine: reproCommand, environment: environment, workingDirectory: task. workingDirectory, dynamicExecutionDelegate: dynamicExecutionDelegate, clientDelegate: clientDelegate, processDelegate: delegate)
545+ outputDelegate. note ( " Crash reproducer created in \( dir. str) " )
546+ }
547+ }
548+ }
549+
529550 if let error = delegate . executionError {
530551 outputDelegate. error ( error)
531552 return . failed
0 commit comments