-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Fallback to .init_array when no arguments are available on glibc Linux #66547
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @joshtriplett (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
You can't always assume that This is a known limitation on Linux, that you can't reliably get the program arguments except by saving them in the main entry point. I don't think we should try to work around that. (And honestly, libraries should ask the application to pass in the arguments the library should use, which might not be the original arguments of the program.) |
I would personally propose closing this, unless a method arises to get the arguments out of the C library or similar. We really appreciate your contribution, however. |
You can put an |
This is implemented in both glibc |
There's also this approach that assumes |
@joshtriplett What do you think about these options? Using |
I've implemented these at https://docs.rs/libargs. |
On November 20, 2019 6:02:33 AM PST, leo60228 ***@***.***> wrote:
@joshtriplett What do you think about these options? Using
`.init_array` only works on glibc, but walking the stack is both hacky
and non-constant-time.
Walking the stack seems like a bad idea, considering that it's legal to change the stack before loading a library, or for that matter call the library on a thread other than the initial thread. And you'd have no way to know if you got valid data.
`.init_array` seems like a reasonable thing for the glibc target to try, given that you'll know if it got called or not. And if someone strips out the `.init_array` section, this fails gracefully. Only do this in the glibc target, though, and we need to document it so that library builders know about it.
|
Where should this be documented? |
On November 21, 2019 5:21:30 AM PST, leo60228 ***@***.***> wrote:
Where should this be documented?
In the documentation of the args functions.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add a platform-specific test for this behavior, so we know if we've done something that makes it stop working?
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other thought: if we initialize arguments this way, we don't also need to initialize them in our main function in binaries. Can you compile out that code on linux-gnu?
Can you confirm that this works in statically linked libraries and statically linked binaries (with static glibc)? |
If the |
I've been having stability issues with my system, and compiling rustc causes a freeze, so I've been using |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Why is this an error? |
Oh, it's because cfgs need to be in |
In
How about marking Also, investigating further, this does work in a binary, including a statically linked binary. Also worth noting, a glibc-based binary or library has content in So, at this point, I think we just need a test, and a bit of cfg logic to make |
Thank you for all the work you've put into this! @rust-lang/libs, does this seem reasonable to you? I think this seems worth doing. |
I would agree this seems reasonable to land, supporting argc/argv access in a cdylib is best effort on a per-platform basis, so adding platform specific code to support it somewhere seems fine by me. |
What's the libs process here? Should this go through rfcbot for libs, or since it doesn't add new API, is the current expressed support sufficient? @leo60228 Could you please rebase -i into a set of logical commits (that don't include reverts or fixes to previous patches, for instance)? |
I'm not entirely sure *why*, but this fixed a problem I was having.
06a3b2f
to
c6bcea9
Compare
Ping from triage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, thanks @leo60228!
@bors r+ |
📌 Commit c6bcea9 has been approved by |
Fallback to .init_array when no arguments are available on glibc Linux Linux is one of the only platforms where `std::env::args` doesn't work in a cdylib.
☀️ Test successful - checks-azure |
Tested on commit rust-lang/rust@3907d59. Direct link to PR: <rust-lang/rust#66547> 💔 miri on linux: test-pass → test-fail (cc @oli-obk @eddyb @RalfJung, @rust-lang/infra).
FYI this is actually not safe like this, see #105999 |
Linux is one of the only platforms where
std::env::args
doesn't work in a cdylib.