Skip to content

Commit 16452e1

Browse files
authored
Frequent crashes in LLBuildProgressTracker while building swift-java on linux and swift 6.1.2 (#8998)
Frequent crashes in LLBuildProgressTracker while building swift-java on linux and swift 6.1.2 ### Motivation: > Thread 4 crashed: > > 0 0x00007f1559da359a swift_slowAlloc + 74 in [libswiftCore.so](http://libswiftcore.so/) > 1 [ra] 0x00007f1559da3877 swift_allocObject + 38 in [libswiftCore.so](http://libswiftcore.so/) > 2 [ra] 0x00007f1559b85571 _allocateStringStorage(codeUnitCapacity:) + 160 in [libswiftCore.so](http://libswiftcore.so/) > 3 [ra] 0x00007f1559d03452 _StringGuts.grow(_:) + 273 in [libswiftCore.so](http://libswiftcore.so/) > 4 [ra] 0x00007f1559bf7e88 specialized static String._fromUTF8Repairing(_:) + 999 in [libswiftCore.so](http://libswiftcore.so/) > 5 [ra] [inlined] [system] 0x000056315a96e7ef specialized String.init<A, B>(decoding:as:) in swift-package at //<compiler-generated> > 6 [ra] [inlined] 0x000056315a96e7ef stringFromData(_:) in swift-package at /home/build-user/llbuild/products/llbuildSwift/Internals.swift:49:12 > 7 [ra] 0x000056315a96e7ef Command.name.getter + 78 in swift-package at /home/build-user/llbuild/products/llbuildSwift/BuildSystemBindings.swift:720:20 > 8 [ra] 0x00005631593a61a2 closure #1 in LLBuildProgressTracker.commandProcessFinished(_:process:result:) + 33 in swift-package at /home/build-user/swiftpm/Sources/Build/LLBuildProgressTracker.swift:347:65 > 9 [ra] [thunk] 0x00005631592f6989 thunk for @escaping @callee_guaranteed @sendable () -> () + 24 in swift-package at //<compiler-generated> ### Modifications: Command is associated with a handle (pointer) that may be reclaimed when this function finishes. ### Result: Do not access command attributes asynchronously
1 parent 53116b5 commit 16452e1

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

Sources/Build/LLBuildProgressTracker.swift

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
279279
guard command.shouldShowStatus else { return }
280280
guard !self.swiftParsers.keys.contains(command.name) else { return }
281281

282+
let commandName = command.name
283+
let commandDescription = command.description
284+
282285
self.queue.async {
283286
if result == .cancelled {
284287
self.cancelled = true
@@ -288,8 +291,8 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
288291
self.delegate?.buildSystem(self.buildSystem, didFinishCommand: BuildSystemCommand(command))
289292

290293
if !self.logLevel.isVerbose && !self.logLevel.isQuiet {
291-
let targetName = self.swiftParsers[command.name]?.targetName
292-
self.taskTracker.commandFinished(command, result: result, targetName: targetName)
294+
let targetName = self.swiftParsers[commandName]?.targetName
295+
self.taskTracker.commandFinished(commandDescription, result: result, targetName: targetName)
293296
self.updateProgress()
294297
}
295298
}
@@ -345,12 +348,15 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
345348
// FIXME: This should really happen at the command-level and is just a stopgap measure.
346349
let shouldFilterOutput = !self.logLevel.isVerbose && command.verboseDescription.hasPrefix("codesign ") && result
347350
.result != .failed
351+
352+
let commandName = command.name
353+
348354
self.queue.async {
349-
if let buffer = self.nonSwiftMessageBuffers[command.name], !shouldFilterOutput {
355+
if let buffer = self.nonSwiftMessageBuffers[commandName], !shouldFilterOutput {
350356
self.progressAnimation.clear()
351357
self.outputStream.send(buffer)
352358
self.outputStream.flush()
353-
self.nonSwiftMessageBuffers[command.name] = nil
359+
self.nonSwiftMessageBuffers[commandName] = nil
354360
}
355361
}
356362

@@ -362,13 +368,13 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
362368
// The command failed, so we queue up an asynchronous task to see if we have any error messages from the
363369
// target to provide advice about.
364370
self.queue.async {
365-
guard let target = self.swiftParsers[command.name]?.targetName else { return }
371+
guard let target = self.swiftParsers[commandName]?.targetName else { return }
366372
guard let errorMessages = self.errorMessagesByTarget[target] else { return }
367373
for errorMessage in errorMessages {
368374
// Emit any advice that's provided for each error message.
369375
if let adviceMessage = self.buildExecutionContext.buildErrorAdviceProvider?.provideBuildErrorAdvice(
370376
for: target,
371-
command: command.name,
377+
command: commandName,
372378
message: errorMessage
373379
) {
374380
self.outputStream.send("note: \(adviceMessage)\n")
@@ -536,8 +542,8 @@ private struct CommandTaskTracker {
536542
}
537543
}
538544

539-
mutating func commandFinished(_ command: SPMLLBuild.Command, result: CommandResult, targetName: String?) {
540-
let progressTextValue = self.progressText(of: command, targetName: targetName)
545+
mutating func commandFinished(_ commandDescription: String, result: CommandResult, targetName: String?) {
546+
let progressTextValue = self.progressText(of: commandDescription, targetName: targetName)
541547
self.onTaskProgressUpdateText?(progressTextValue, targetName)
542548

543549
self.latestFinishedText = progressTextValue
@@ -564,27 +570,27 @@ private struct CommandTaskTracker {
564570
}
565571
}
566572

567-
private func progressText(of command: SPMLLBuild.Command, targetName: String?) -> String {
573+
private func progressText(of commandDescription: String, targetName: String?) -> String {
568574
#if os(Windows)
569575
let pathSep: Character = "\\"
570576
#else
571577
let pathSep: Character = "/"
572578
#endif
573579
// Transforms descriptions like "Linking ./.build/x86_64-apple-macosx/debug/foo" into "Linking foo".
574-
if let firstSpaceIndex = command.description.firstIndex(of: " "),
575-
let lastDirectorySeparatorIndex = command.description.lastIndex(of: pathSep)
580+
if let firstSpaceIndex = commandDescription.firstIndex(of: " "),
581+
let lastDirectorySeparatorIndex = commandDescription.lastIndex(of: pathSep)
576582
{
577-
let action = command.description[..<firstSpaceIndex]
578-
let fileNameStartIndex = command.description.index(after: lastDirectorySeparatorIndex)
579-
let fileName = command.description[fileNameStartIndex...]
583+
let action = commandDescription[..<firstSpaceIndex]
584+
let fileNameStartIndex = commandDescription.index(after: lastDirectorySeparatorIndex)
585+
let fileName = commandDescription[fileNameStartIndex...]
580586

581587
if let targetName {
582588
return "\(action) \(targetName) \(fileName)"
583589
} else {
584590
return "\(action) \(fileName)"
585591
}
586592
} else {
587-
return command.description
593+
return commandDescription
588594
}
589595
}
590596

0 commit comments

Comments
 (0)