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

Windows Command: Don't run batch files using verbatim paths #95246

Merged
merged 5 commits into from
Apr 25, 2022

Conversation

ChrisDenton
Copy link
Member

Fixes #95178

Note that the first commit does some minor refactoring (moving command line argument building to args.rs). The actual changes are in the second.

@rust-highfive
Copy link
Collaborator

r? @joshtriplett

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 23, 2022
@ChrisDenton
Copy link
Member Author

ChrisDenton commented Mar 23, 2022

This is also a first step toward #94743. Rust no longer relies on the undocumented behaviour of CreateProcessW to run batch files. Instead it knows how to run them explicitly.

I also want to eventually do further refactoring of argument building. Given the growing number of options, a builder struct may be more appropriate. But I don't want to do that all in one PR.

EDIT: Oh and this PR lays the ground work for users being able to set argv[0] which would be nice to implement at some point.

@rust-log-analyzer

This comment has been minimized.

@joshtriplett
Copy link
Member

LGTM, r=me with the message nit fixed.

@joshtriplett
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Mar 25, 2022

📌 Commit 7200afa has been approved by joshtriplett

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 25, 2022
@bors
Copy link
Contributor

bors commented Mar 25, 2022

⌛ Testing commit 7200afa with merge b1651f12488d9ae50ccab10fce5c90e92a938d40...

@bors
Copy link
Contributor

bors commented Mar 25, 2022

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 25, 2022
@rust-log-analyzer

This comment has been minimized.

@ChrisDenton
Copy link
Member Author

Hm, the failure is caused by https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/issue-15149.rs.
Which is a test added for #15149. The test ends up specifically testing if argv[0] ends with .exe. It should probably be testing env::current_exe() instead.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 25, 2022
@ChrisDenton
Copy link
Member Author

Oh, looks like my format-on-save has been to work on that file. The actual changes are lines 8, 22 and 23.

@apiraino apiraino added T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 14, 2022
@ChrisDenton ChrisDenton added the O-windows Operating system: Windows label Apr 24, 2022
@joshtriplett
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Apr 24, 2022

📌 Commit 4a0ec50 has been approved by joshtriplett

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 24, 2022
@bors
Copy link
Contributor

bors commented Apr 25, 2022

⌛ Testing commit 4a0ec50 with merge 756ffb8...

@bors
Copy link
Contributor

bors commented Apr 25, 2022

☀️ Test successful - checks-actions
Approved by: joshtriplett
Pushing 756ffb8 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Apr 25, 2022
@bors bors merged commit 756ffb8 into rust-lang:master Apr 25, 2022
@rustbot rustbot added this to the 1.62.0 milestone Apr 25, 2022
@ChrisDenton ChrisDenton deleted the command-args branch April 25, 2022 10:35
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (756ffb8): comparison url.

Summary:

  • Primary benchmarks: 😿 relevant regression found
  • Secondary benchmarks: no relevant changes found
Regressions 😿
(primary)
Regressions 😿
(secondary)
Improvements 🎉
(primary)
Improvements 🎉
(secondary)
All 😿 🎉
(primary)
count1 1 0 0 0 1
mean2 0.3% N/A N/A N/A 0.3%
max 0.3% N/A N/A N/A 0.3%

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

Footnotes

  1. number of relevant changes

  2. the arithmetic mean of the percent change

@shuffle2
Copy link

shuffle2 commented May 21, 2022

hi @ChrisDenton . I'm writing some rust code that needs argv identically to the way a C/C++ application would receive them (on modern windows). I was thrown off for some time because of the comments above the parse_lp_cmd_line seem to point to the wrong things. In actuality, "normal" CRT-based apps on windows use ucrtbase.dll!_configure_wide_argv (or the narrow one) to parse the command line. The source for this gets installed into e.g. C:\Program Files (x86)\Windows Kits\10\Source\10.0.22000.0\ucrt\startup\argv_parsing.cpp when you install the build tools. I just thought I'd mention it because I was confused about the apparent implementation by trial and error in rust to adhere to this behavior for which the source is actually available - I thought maybe you weren't aware.

afaict at least the daviddeley.com link and the mention of shell32 are therefor out-of-date and/or wrong.

I'll probably still reimplement it for my project...(it just makes sense for me to not implicitly depend on windows std :))

@ChrisDenton
Copy link
Member Author

hi @shuffle2, thanks for the comment!

I'm aware that the ucrt source is available but I've avoided looking at it because I'm unclear if that would cause licensing issues. I'm not a lawyer and haven't hired one so I've taken the cautious approach as I don't want to cause problems for the Rust project in the future.

For now I'm going on public information and my own experimentation. If anyone wanted to write a more accurate description then that would be very welcome!

@shuffle2
Copy link

[continuing this conversion here... :)]

after looking at stuff a bit more, I realized that rust executables are already linking against and executing this code in ucrt. If you dynamic link against crt it's obvious by looking for imports from "api-ms-win-crt-*" libraries (these all get routed to ucrtbase.dll under the hood). In either case (dynamic or static link against crt), the function pre_c_initialization will be called before main (which is where the actual rust code begins). pre_c_initialization will (among other things) perform the initialization of argv. As far as I can tell, rust is also always compiling against ucrt in non-unicode mode (the argv and etc are using the "narrow" methods).

So, this created more questions than answers unfortunately:

  1. Is rust knowingly linking against ucrt? Since target-feature=+crt-static is well documented I assume it's intentional, even though it's not yet clear to me where rust actually depends on it. Any idea what the reasoning is here? (maybe rust depends on ucrt to provide some machinery like TLS/stack cookie/other OS integrations?)
  2. If rust already depends on ucrt for some reason, can we make it use wide characters (probably it should anyway, just to lessen possible confusion/footguns), and then just use the argv it has prepared? It's not clear to me why rust would let ucrt do the work but ignore the result.

@ChrisDenton
Copy link
Member Author

The standard library does not decide on the program's entry point. That's the job of the Rust compiler. If you think it should instead use wmain and pass arguments to the std, then you should definitely open a new issue about that rather than discussing it on an unrelated and closed PR that's likely only being read by me. 🙂

Is rust knowingly linking against ucrt?

MSVC Rust needs the vcruntime for mem* functions and C++ exceptions. This in turn depends on having a crt. Rust also uses the C runtime for process startup/shutdown code and running pre-main initializers. So yes, it's "knowingly" linking against ucrt but it's incidental and could even change in the future (e.g. if we decide to reimplement the needed bits in pure Rust for some reason).

MinGW Rust does not link against the UCRT and so that toolchain will have different parsing rules. There can also be third-party toolchains that do their own thing (or skip arguments entirely). And even MSVC allows changing or disabling the parsing using special object files.

It may be surprising if std::env::args varied between Rust programs. Then again, this may be something you'd want. Either way I do think this should be a new issue.

@shuffle2
Copy link

shuffle2 commented May 25, 2022

The standard library does not decide on the program's entry point. That's the job of the Rust compiler.

Sure, I was mostly surprised that ucrt is involved at all - assumed it would be completely replaced, if replaced at all.

If you think it should instead use wmain and pass arguments to the std, then you should definitely open a new issue about that rather than discussing it on an unrelated and closed PR that's likely only being read by me. 🙂

yes well, I stalked the git blame and picked someone who had modified the code recently :D I'm not really sure where is a good forum for this topic - I checked discord and zulip and they seem unrelated and/or inactive. If just filing a github issue is the way, then I'll do that (eventually). Thanks!

@ChrisDenton
Copy link
Member Author

Zulip would also be a great place to ask. Many people involved with Rust (both compiler and libs) are active there.

In general closed PRs are somewhat "hidden" because few people will notice new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. O-windows Operating system: Windows S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

Windows Command regression - broken paths
9 participants