Skip to content

Commit 08a17a9

Browse files
Merge pull request #1961 from cachemeifyoucan/eng/PR-crash-repro-improvment
CrashReproducer generation improvements
2 parents d1942f8 + b4dcc1e commit 08a17a9

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,12 @@ extension Driver {
10871087
reproJob.commandLine.appendFlag(.genReproducer)
10881088
reproJob.commandLine.appendFlag(.genReproducerDir)
10891089
reproJob.commandLine.appendPath(output)
1090+
reproJob.commandLine.removeAll {
1091+
guard case let .flag(opt) = $0 else {
1092+
return false
1093+
}
1094+
return opt == Option.frontendParseableOutput.spelling
1095+
}
10901096
reproJob.outputs.removeAll()
10911097
reproJob.outputCacheKeys.removeAll()
10921098
return reproJob

Sources/SwiftDriverExecution/MultiJobExecutor.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import class TSCBasic.DiagnosticsEngine
2323
import class TSCBasic.Process
2424
import protocol TSCBasic.DiagnosticData
2525
import protocol TSCBasic.FileSystem
26+
import struct TSCBasic.AbsolutePath
2627
import struct TSCBasic.Diagnostic
2728
import struct TSCBasic.ProcessResult
2829
import func TSCBasic.withTemporaryDirectory
@@ -678,7 +679,13 @@ class ExecuteJobRule: LLBuildRule {
678679
}
679680

680681
private func handleSignalledJob(for job: Job) throws {
681-
try withTemporaryDirectory(dir: fileSystem.tempDirectory, prefix: "swift-reproducer", removeTreeOnDeinit: false) { tempDir in
682+
let reproDir: AbsolutePath
683+
if let pathFromEnv = context.env["SWIFT_CRASH_DIAGNOSTICS_DIR"] {
684+
reproDir = try AbsolutePath(validating: pathFromEnv)
685+
} else {
686+
reproDir = try fileSystem.tempDirectory
687+
}
688+
try withTemporaryDirectory(dir: reproDir, prefix: "swift-crash-reproducer", removeTreeOnDeinit: false) { tempDir in
682689
guard let reproJob = context.executorDelegate.getReproducerJob(job: job, output: VirtualPath.absolute(tempDir)) else {
683690
return
684691
}

Tests/SwiftDriverTests/CachingBuildTests.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,52 @@ final class CachingBuildTests: XCTestCase {
10531053
}
10541054
}
10551055

1056+
func testCrashReproducer() throws {
1057+
try withTemporaryDirectory { path in
1058+
try localFileSystem.changeCurrentWorkingDirectory(to: path)
1059+
let moduleCachePath = path.appending(component: "ModuleCache")
1060+
let casPath = path.appending(component: "cas")
1061+
try localFileSystem.createDirectory(moduleCachePath)
1062+
let main = path.appending(component: "testCachingBuild.swift")
1063+
let mainFileContent = "import C;"
1064+
try localFileSystem.writeFileContents(main) {
1065+
$0.send(mainFileContent)
1066+
}
1067+
let cHeadersPath: AbsolutePath =
1068+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
1069+
.appending(component: "CHeaders")
1070+
let swiftModuleInterfacesPath: AbsolutePath =
1071+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
1072+
.appending(component: "Swift")
1073+
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
1074+
var env = ProcessEnv.block
1075+
env["SWIFT_CRASH_DIAGNOSTICS_DIR"] = path.nativePathString(escaped: true)
1076+
var driver = try Driver(args: ["swiftc",
1077+
"-I", cHeadersPath.nativePathString(escaped: true),
1078+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
1079+
"-explicit-module-build", "-enable-deterministic-check",
1080+
"-module-cache-path", moduleCachePath.nativePathString(escaped: true),
1081+
"-cache-compile-job", "-cas-path", casPath.nativePathString(escaped: true),
1082+
"-working-directory", path.nativePathString(escaped: true),
1083+
"-Xfrontend", "-debug-crash-after-parse",
1084+
main.nativePathString(escaped: true)] + sdkArgumentsForTesting,
1085+
env: env)
1086+
guard driver.isFrontendArgSupported(.genReproducer) else {
1087+
throw XCTSkip("crash reproducer not supported")
1088+
}
1089+
let jobs = try driver.planBuild()
1090+
do {
1091+
try driver.run(jobs: jobs)
1092+
XCTFail("Build should fail")
1093+
} catch {
1094+
XCTAssertTrue(driver.diagnosticEngine.hasErrors)
1095+
XCTAssertTrue(driver.diagnosticEngine.diagnostics.contains {
1096+
$0.message.behavior == .note && $0.message.data.description.starts(with: "crash reproducer")
1097+
})
1098+
}
1099+
}
1100+
}
1101+
10561102
func testDeterministicCheck() throws {
10571103
try withTemporaryDirectory { path in
10581104
try localFileSystem.changeCurrentWorkingDirectory(to: path)

0 commit comments

Comments
 (0)