Skip to content
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

[musl] use posix_spawn if a directory change was requested #131851

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sunshowers
Copy link
Contributor

@sunshowers sunshowers commented Oct 17, 2024

Currently, not all libcs have the posix_spawn_file_actions_addchdir_np symbol available to them. So we attempt to do a weak symbol lookup for that function. But that only works if libc is a dynamic library -- with statically linked musl binaries the symbol lookup would never work, so we would never be able to use it even if the musl in use supported the symbol.

Now that Rust has a minimum musl version of 1.2.3, all supported musl versions now include this symbol, so we can unconditionally expect it to be there. This symbol was added to libc in rust-lang/libc#3949 -- use it here.

I couldn't find any tests for whether the posix_spawn path is used, but I've verified with cargo-nextest that this change works. This is a substantial improvement to nextest's performance with musl. On my workstation with a Ryzen 7950x, against https://github.com/clap-rs/clap at
61f5ee514f8f60ed8f04c6494bdf36c19e7a8126:

Before:

     Summary [   1.071s] 879 tests run: 879 passed, 0 skipped

After:

     Summary [   0.392s] 879 tests run: 879 passed, 0 skipped

Fixes #99740.

try-job: dist-various-1
try-job: dist-various-2

@rustbot
Copy link
Collaborator

rustbot commented Oct 17, 2024

r? @workingjubilee

rustbot has assigned @workingjubilee.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added O-unix Operating system: Unix-like S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 17, 2024
@rustbot
Copy link
Collaborator

rustbot commented Oct 17, 2024

These commits modify the library/Cargo.lock file. Unintentional changes to library/Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@rust-log-analyzer

This comment has been minimized.

@the8472
Copy link
Member

the8472 commented Oct 17, 2024

I couldn't find any tests for whether the posix_spawn path is used

Well, posix_spawn is an implementation detail, so there's no API that would let you distinguish that.

But you can do the opposite: Have a test that covers command.current_dir() (this test already exists) and hope that it uses posix_spawn (which can be manually verified via strace) and then write a second test that combines current_dir and pre_exec to make sure the fork path gets exercised too.

// exercise the fork/exec path since the earlier attempts may have used pidfd_spawnp()
let mut child =
unsafe { Command::new("false").pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap();

@workingjubilee
Copy link
Member

Hm. I guess one can write internal unit-tests where the APIs are exposed? But doing that with multiprocess situations sounds... treacherous.

@sunshowers
Copy link
Contributor Author

Yeah, a test attempting to exercise both paths sounds good. I'll work on that once #131823 lands.

Hm. I guess one can write internal unit-tests where the APIs are exposed? But doing that with multiprocess situations sounds... treacherous.

What I would personally do is abstract the posix_spawn/fork decision into a function which returns an enum, and test that. I don't know how feasible that is, and I'd rather not block this relatively straightforward PR on that refactor :)

@workingjubilee
Copy link
Member

Yeah, I don't wanna scope creep ya.

@sunshowers
Copy link
Contributor Author

All right, rebased and added a test to exercise both paths.

@rust-log-analyzer

This comment has been minimized.

Currently, not all libcs have the `posix_spawn_file_actions_addchdir_np` symbol
available to them. So we attempt to do a weak symbol lookup for that function.
But that only works if libc is a dynamic library -- with statically linked musl
binaries the symbol lookup would never work, so we would never be able to use it
even if the musl in use supported the symbol.

Now that Rust has a minimum musl version of 1.2.3, all supported musl versions
now include this symbol, so we can unconditionally expect it to be there. This
symbol was added to libc in rust-lang/libc#3949 -- use
it here.

I couldn't find any tests for whether the posix_spawn path is used, but I've
verified with cargo-nextest that this change works. This is a substantial
improvement to nextest's performance with musl. On my workstation with a Ryzen
7950x, against https://github.com/clap-rs/clap at
61f5ee514f8f60ed8f04c6494bdf36c19e7a8126:

Before:

```
     Summary [   1.071s] 879 tests run: 879 passed, 0 skipped
```

After:

```
     Summary [   0.392s] 879 tests run: 879 passed, 0 skipped
```

Fixes rust-lang#99740.
Comment on lines +877 to +878
#[cfg(not(all(target_os = "linux", target_env = "musl")))]
fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
Copy link
Member

@workingjubilee workingjubilee Oct 19, 2024

Choose a reason for hiding this comment

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

You've moved this to the top of scope in a sensible-seeming fashion. Unfortunately, this is only called within posix_spawn, which not every platform calls to begin with. Indeed, many cfg it away! So this will not be called at all on platforms that don't match this cfg:

    #[cfg(any(
        target_os = "freebsd",
        all(target_os = "linux", target_env = "gnu"),
        all(target_os = "linux", target_env = "musl"),
        target_os = "nto",
        target_vendor = "apple",
    ))]

But it will still be defined for those. For those which aren't in the above set, but do use process_unix.rs, then they will see an unused function, and then libstd will not build.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, right...

I guess I could probably move the function item to be function-local.

@workingjubilee
Copy link
Member

@bors try

@bors
Copy link
Contributor

bors commented Oct 19, 2024

⌛ Trying commit a9016c8 with merge b641764...

bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 19, 2024
[musl] use posix_spawn if a directory change was requested

Currently, not all libcs have the `posix_spawn_file_actions_addchdir_np` symbol available to them. So we attempt to do a weak symbol lookup for that function. But that only works if libc is a dynamic library -- with statically linked musl binaries the symbol lookup would never work, so we would never be able to use it even if the musl in use supported the symbol.

Now that Rust has a minimum musl version of 1.2.3, all supported musl versions now include this symbol, so we can unconditionally expect it to be there. This symbol was added to libc in rust-lang/libc#3949 -- use it here.

I couldn't find any tests for whether the posix_spawn path is used, but I've verified with cargo-nextest that this change works. This is a substantial improvement to nextest's performance with musl. On my workstation with a Ryzen 7950x, against https://github.com/clap-rs/clap at
61f5ee514f8f60ed8f04c6494bdf36c19e7a8126:

Before:

```
     Summary [   1.071s] 879 tests run: 879 passed, 0 skipped
```

After:

```
     Summary [   0.392s] 879 tests run: 879 passed, 0 skipped
```

Fixes rust-lang#99740.

try-job: dist-various-1
try-job: dist-various-2
@rust-log-analyzer
Copy link
Collaborator

The job dist-various-2 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
file:.git/config remote.origin.url=https://github.com/rust-lang-ci/rust
file:.git/config remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
file:.git/config gc.auto=0
file:.git/config http.https://github.com/.extraheader=AUTHORIZATION: basic ***
file:.git/config branch.try.remote=origin
file:.git/config branch.try.merge=refs/heads/try
file:.git/config remote.upstream.fetch=+refs/heads/*:refs/remotes/upstream/*
file:.git/config submodule.library/backtrace.active=true
file:.git/config submodule.library/backtrace.url=https://github.com/rust-lang/backtrace-rs.git
file:.git/config submodule.library/stdarch.active=true

@bors
Copy link
Contributor

bors commented Oct 19, 2024

💔 Test failed - checks-actions

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 19, 2024
@workingjubilee
Copy link
Member

workingjubilee commented Oct 19, 2024

yep, goes kaput on the solaris build.

you may want to cross-compile for the illumos stdlib while testing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-unix Operating system: Unix-like S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

posix_spawn_file_actions_addchdir_np lookup doesn't work on linux musl
7 participants