Skip to content

Reset the working directory of child processes we spawn on Windows.#1212

Merged
grynspan merged 10 commits into
mainfrom
jgrynspan/1209-working-directories-are-terrible
Jul 8, 2025
Merged

Reset the working directory of child processes we spawn on Windows.#1212
grynspan merged 10 commits into
mainfrom
jgrynspan/1209-working-directories-are-terrible

Conversation

@grynspan

@grynspan grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor

This PR modifies the Windows implementation of spawnProcess() so that it sets the working directory of the new process to "C:" (or thereabouts). This prevents a race condition on Windows because that system won't let you delete a directory if it's the working directory of any process. See The Old New Thing for a very on-the-nose blog post.

Note that we do not specify the value of the working directory in an exit test body. A test should generally not rely on it anyway because it is global state and any thread could change its value at any time.

I haven't written a unit test for this change because it's unclear what I could write that would be easily verifiable, and because I don't know what state I might perturb outside such a test by calling SetCurrentDirectory().

Resolves #1209.
(This is a speculative fix.)

Checklist:

  • Code and documentation should follow the style of the Style Guide.
  • If public symbols are renamed or modified, DocC references should be updated.

@grynspan grynspan added this to the Swift 6.x (main) milestone Jul 8, 2025
@grynspan grynspan self-assigned this Jul 8, 2025
@grynspan grynspan added bug 🪲 Something isn't working windows 🪟 Windows support workaround Workaround for an issue in another component (may need to revert later) exit-tests ☠️ Work related to exit tests labels Jul 8, 2025
@grynspan grynspan requested a review from jmschonfeld July 8, 2025 04:22
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

3 similar comments
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test Linux

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

1 similar comment
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

I'm not planning to apply the same change to the posix_spawn() path (using posix_spawn_file_actions_addchdir_np()), but if we decide we need it: posix_spawn_file_actions_addchdir.txt

@jmschonfeld jmschonfeld left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems fine to me. Agreed that making a similar change to the posix spawn path seems like a good idea. The temporary directory might also be a good CWD to use instead of the root directory if it's easier to get to / works better but the root directory seems fine too given that exit tests likely shouldn't rely on the CWD

Comment thread Sources/Testing/Support/FileHandle.swift Outdated
@grynspan grynspan requested a review from compnerd July 8, 2025 17:30
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

Comment thread Sources/Testing/Support/FileHandle.swift
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

1 similar comment
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test Windows

This PR modifies the Windows implementation of `spawnProcess()` so that it
sets the working directory of the new process to "C:\" (or thereabouts). This
prevents a race condition on Windows because that system won't let you delete a
directory if it's the working directory of any process. See
[The Old New Thing](https://devblogs.microsoft.com/oldnewthing/20101109-00/?p=12323)
for a very on-the-nose blog post.

Note that we do not specify the value of the working directory in an exit test
body. A test should generally not rely on it anyway because it is global state
and any thread could change its value at any time.

I haven't written a unit test for this change because it's unclear what I could
write that would be easily verifiable, and because I don't know what state I
might perturb outside such a test by calling `SetCurrentDirectory()`.

Resolves #1209.
(This is a speculative fix.)
@grynspan grynspan force-pushed the jgrynspan/1209-working-directories-are-terrible branch from 1dea725 to 7cb5040 Compare July 8, 2025 18:17
@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test Linux

@grynspan

grynspan commented Jul 8, 2025

Copy link
Copy Markdown
Contributor Author

@swift-ci test macOS

@grynspan grynspan merged commit f9f25bf into main Jul 8, 2025
3 checks passed
@grynspan grynspan deleted the jgrynspan/1209-working-directories-are-terrible branch July 8, 2025 19:15
grynspan added a commit that referenced this pull request Jul 10, 2025
…1212)

This PR modifies the Windows implementation of `spawnProcess()` so that
it sets the working directory of the new process to "C:\" (or
thereabouts). This prevents a race condition on Windows because that
system won't let you delete a directory if it's the working directory of
any process. See [The Old New
Thing](https://devblogs.microsoft.com/oldnewthing/20101109-00/?p=12323)
for a very on-the-nose blog post.

Note that we do not specify the value of the working directory in an
exit test body. A test should generally not rely on it anyway because it
is global state and any thread could change its value at any time.

I haven't written a unit test for this change because it's unclear what
I could write that would be easily verifiable, and because I don't know
what state I might perturb outside such a test by calling
`SetCurrentDirectory()`.

Resolves #1209.
(This is a speculative fix.)

### Checklist:

- [x] Code and documentation should follow the style of the [Style
Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md).
- [x] If public symbols are renamed or modified, DocC references should
be updated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🪲 Something isn't working exit-tests ☠️ Work related to exit tests windows 🪟 Windows support workaround Workaround for an issue in another component (may need to revert later)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exit tests crash main process on Windows (testing fails)

6 participants