Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 8, 2025

Conversation

grynspan
Copy link
Contributor

@grynspan grynspan commented Jul 8, 2025

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
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

3 similar comments
@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test Linux

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

1 similar comment
@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

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

Copy link

@jmschonfeld jmschonfeld left a comment

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

@grynspan grynspan requested a review from compnerd July 8, 2025 17:30
@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

1 similar comment
@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@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
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@swift-ci test Linux

@grynspan
Copy link
Contributor Author

grynspan commented Jul 8, 2025

@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
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