Skip to content

[Driver] Fix temporary directory leak when running inplace jobs#2095

Draft
ramonasuncion wants to merge 1 commit into
swiftlang:mainfrom
ramonasuncion:swift-driver-fix-temp-dir
Draft

[Driver] Fix temporary directory leak when running inplace jobs#2095
ramonasuncion wants to merge 1 commit into
swiftlang:mainfrom
ramonasuncion:swift-driver-fix-temp-dir

Conversation

@ramonasuncion
Copy link
Copy Markdown
Member

@ramonasuncion ramonasuncion commented Feb 27, 2026

Closes #2049

The defer block doesn't run because execute doesn't return on success, but defer is still needed for all other exit paths.

defer {
// Attempt to cleanup temporary files before exiting, unless -save-temps was passed or a job crashed.
if !parsedOptions.hasArgument(.saveTemps) && !toolExecutionDelegate.anyJobHadAbnormalExit {
try? executor.resolver.removeTemporaryDirectory()
}
}

@ramonasuncion
Copy link
Copy Markdown
Member Author

@swift-ci test

1 similar comment
@ramonasuncion
Copy link
Copy Markdown
Member Author

@swift-ci test

@ramonasuncion
Copy link
Copy Markdown
Member Author

Actually, I'll probably extract the cleanup to a function.

Copy link
Copy Markdown
Contributor

@owenv owenv left a comment

Choose a reason for hiding this comment

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

Moving the deletion before the driver re-execs isn't sufficient here because the temporary directory might contain e.g. a response file required by the job we re-exec to

@ramonasuncion
Copy link
Copy Markdown
Member Author

Moving the deletion before the driver re-execs isn't sufficient here because the temporary directory might contain e.g. a response file required by the job we re-exec to

Oop. This is more involved. I'll get back to you, I need to do more digging. 😅

@ramonasuncion ramonasuncion marked this pull request as draft March 2, 2026 20:35
@ramonasuncion
Copy link
Copy Markdown
Member Author

@owenv Does this make sense? I'm thinking of changing up ArgResolver so that it only creates a temporaryDirectory when resolveArgumentList actually uses one since it's always creating one upfront:

// FIXME: withTemporaryDirectory uses FileManager.default, need to create a FileSystem.temporaryDirectory api.
let tmpDir: AbsolutePath = try withTemporaryDirectory(removeTreeOnDeinit: false) { path in
// FIXME: TSC removes empty directories even when removeTreeOnDeinit is false. This seems like a bug.
try fileSystem.writeFileContents(path.appending(component: ".keep-directory")) { $0.send("") }
return path
}
self.temporaryDirectory = .absolute(tmpDir)

In SwiftDriverExecutor.swift, I could update the existing if job.requiresInPlaceExecution check to also see whether the temp directory is being used: if not, continue calling exec, otherwise run a child process so defer is called.

if job.requiresInPlaceExecution {
for (envVar, value) in job.extraEnvironmentBlock {
try ProcessEnv.setVar(envVar.value, value: value)
}
try exec(path: arguments[0], args: arguments)
} else {
var childEnv = env
childEnv.merge(job.extraEnvironmentBlock, uniquingKeysWith: { (_, new) in new })
let process : ProcessProtocol
if job.inputs.contains(TypedVirtualPath(file: .standardInput, type: .swift)) {
process = try Process.launchProcessAndWriteInput(
arguments: arguments, env: childEnv, inputFileHandle: FileHandle.standardInput
)
} else {
process = try Process.launchProcess(arguments: arguments, env: childEnv)
}
return try process.waitUntilExit()
}
}

I think it's mainly just moving the different execution paths around. I’ve never used Swift, so hopefully this isn’t too hard to implement.

@ramonasuncion
Copy link
Copy Markdown
Member Author

ramonasuncion commented Mar 4, 2026

It's probably easier if I try to implement it and you give me feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

print-target-info: Temporary Directory isn't cleaned up on Linux/FreeBSD

2 participants