Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions Plugins/AWSLambdaPackager/PluginUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,19 @@ struct Utils {
if let customWorkingDirectory {
process.currentDirectoryURL = URL(fileURLWithPath: customWorkingDirectory.path())
}
process.terminationHandler = { _ in
outputQueue.async {
outputHandler(try? pipe.fileHandleForReading.readToEnd())
}
}

try process.run()
process.waitUntilExit()

// wait for output to be full processed
// Stop the readability handler before reading remaining data to avoid
// a race between the handler and readToEnd() on Linux, which can cause
// a SIGSEGV in the Swift runtime's metadata resolution.
pipe.fileHandleForReading.readabilityHandler = nil

// Read any remaining data from the pipe
outputQueue.async { outputHandler(try? pipe.fileHandleForReading.readToEnd()) }

// wait for output to be fully processed
outputSync.wait()
Comment on lines +104 to 108
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outputSync.wait() is not guaranteed to wait for the final outputQueue.async (or any pending readability-handler enqueues), because outputSync.enter() happens inside outputHandler after the async work has started. If wait() runs before the async block executes, the group count is still 0 and wait() can return early, causing truncated output and potential mutation of outputMutex after output is read. Move the DispatchGroup enter/leave to wrap each outputQueue.async submission (or drain the queue with outputQueue.sync {} / use outputQueue.sync for the final readToEnd).

Copilot uses AI. Check for mistakes.

let output = outputMutex.withLock { $0 }
Expand Down
Loading