-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Use functions from crt_externs.h
on iOS/tvOS/watchOS/visionOS
#125225
Conversation
This should be slightly more correct, and matches the implementation in other programming languages: - [Python's `os.environ`](https://github.com/python/cpython/blob/v3.12.3/Modules/posixmodule.c#L1562-L1566). - [Swift's `Darwin.environ`](https://github.com/apple/swift-corelibs-foundation/blob/swift-5.10-RELEASE/CoreFoundation/Base.subproj/CFPlatform.c#L1811-L1812), though that library is bundled on the system, so they can change it if they want. - [Dart/Flutter](https://github.com/dart-lang/sdk/blob/3.4.0/runtime/bin/platform_macos.cc#L205-L234), doesn't support environment variables on iOS. - Node seems to not be entirely consistent with it: - [`process.c`](https://github.com/nodejs/node/blob/v22.1.0/deps/uv/src/unix/process.c#L38). - [`unix/core.c`](https://github.com/nodejs/node/blob/v22.1.0/deps/uv/src/unix/core.c#L59). - [.NET/Xamarin](https://github.com/dotnet/runtime/blob/v8.0.5/src/native/libs/configure.cmake#L1099-L1106). - [OpenJDK](https://github.com/openjdk/jdk/blob/jdk-23%2B22/src/java.base/unix/native/libjava/ProcessEnvironment_md.c#L31-L33).
If we're comfortable using `_NSGetEnviron` from `crt_externs.h`, there shouldn't be an issue with using these either, and then we can merge with the macOS implementation. This also fixes two test cases on Mac Catalyst: - `tests/ui/command/command-argv0.rs`, maybe because `[[NSProcessInfo processInfo] arguments]` somehow converts the name of the first argument? - `tests/ui/env-funky-keys.rs` since we no longer link to Foundation.
I probably can't accept this in its current form, the way we handle args on macOS has problems:
We need to make getting args on all platforms Much Less Clever. |
Technically this diff is not making the situation worse I suppose? Hmm... and apparently things like googletest straight-up mutate the pointees of these, eesh... What do you think? |
I'm not entirely sure I understand your linked issues? How could we implement these in a "Much Less Clever" way on macOS, while still allowing it to work in dynamic libraries?
Indeed, there aren't any functional changes on macOS, and
Pretty sure that mutating these in
|
Interesting. ...hmm, actually, one thing I noticed through all this. MacOS was never hardened against foolishness the same way that Linux was. @madsmtm A program can update the pointee of the value of |
From my reading of the disassembly of
And instead, when encountering a I've implemented this behaviour in the latest commit. |
@madsmtm Hmm. Are you saying this doesn't work? #include "whatever.h"
int overflow_argc() {
*_NSGetArgc() = 9001;
return 0;
} |
Well... It's kinda muddied by the fact that But if something else is loaded before This can be seen with the following: // File: overflow_argc.c
#import <crt_externs.h>
__attribute__((constructor)) // Run the function upon loading this dylib
void overflow_argc(void) {
*_NSGetArgc() = 9001;
} // File: read_args.m
#import <Foundation/Foundation.h>
#import <crt_externs.h>
int main(int argc, const char * argv[]) {
NSLog(@"argc: %i", argc);
NSLog(@"*_NSGetArgc(): %i", *_NSGetArgc());
NSLog(@"-[NSProcessInfo arguments]: %@", [[NSProcessInfo processInfo] arguments]);
return 0;
} Compile with: clang overflow_argc.c -dynamiclib -o liboverflow_argc.dylib
clang read_args.m -L . -framework Foundation -l overflow_argc Running |
Hmm. Based on what you said, |
For this exact moment I am most concerned about the behavior of Rust code compiled into a cdylib using this version of the standard library, assuming this patch is accepted, and then run with a C host that uses essentially no meaningful library code beyond the barest minimum, so my only question is "Can that C host make us do a UB by being reckless while updating the pointees of these functions in a way we can easily avoid?" |
Yes.
Yeah, I get the concern - and the answer right now is yes, we get UB if some random C code sets the value of And we definitely could just do a That is, well-behaving C code like the following (at least arguably more well-behaving than setting #import <crt_externs.h>
__attribute__((constructor)) // Run the function upon loading this dylib
void erase_first_arg(void) {
*_NSGetArgv()[1] = 0; // Erase first argument
} Would erase the first argument of So I think the question here is more: What is the semantics of |
Hm. As far as C is concerned, there is no real question here: the semantics of argv is that it is null-terminated, thus the only sensible behavior when you assign NULL to a value is that everything stops there. The Objective-C code obeys a different semantic. While there is no question as to whether or not Objective-C code has a place on macOS and even defines much of the platform's properties, thus we should not simply shrug off this behavior, nonetheless the real question that is hanging in the air is: ...Why did an Apple engineer commit that change? ...Unfortunately, the reputation of the company is that they will not be forthcoming with answers, even if we ask, so we are left to speculate. I feel I can assume their decision is not meritless, but I don't know if they were weighing things the same way. Hm. I'll sleep on it. |
I'll add a bit more context for your deliberations:
So another solution could be to skip (i.e. For myself, I think I slightly prefer the " |
We do not support such platforms so I don't think we have to worry about that. A platform either supports at least ANSI C or it doesn't support C at all, to us.
Hm. What I am currently struggling to believe is that there are cases where the |
...In other words, for all major libraries I am aware of, A major benefit I could see of the
|
Yeah, mostly noted it as a curiosity / an explanation for why
Fair point. I've pushed a new commit that merges the implementation on Apple with that of the other unixes, so that we use the " |
That commentary looks good to me! |
@bors r+ |
…iaskrgr Rollup of 7 pull requests Successful merges: - rust-lang#124570 (Miscellaneous cleanups) - rust-lang#124772 (Refactor documentation for Apple targets) - rust-lang#125011 (Add opt-for-size core lib feature flag) - rust-lang#125218 (Migrate `run-make/no-intermediate-extras` to new `rmake.rs`) - rust-lang#125225 (Use functions from `crt_externs.h` on iOS/tvOS/watchOS/visionOS) - rust-lang#125266 (compiler: add simd_ctpop intrinsic) - rust-lang#125348 (Small fixes to `std::path::absolute` docs) Failed merges: - rust-lang#125296 (Fix `unexpected_cfgs` lint on std) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#125225 - madsmtm:ios-crt_externs.h, r=workingjubilee Use functions from `crt_externs.h` on iOS/tvOS/watchOS/visionOS Use `_NSGetEnviron`, `_NSGetArgc` and `_NSGetArgv` on iOS/tvOS/watchOS/visionOS, see each commit and the code comments for details. This allows us to unify more code with the macOS implementation, as well as avoiding linking to the `Foundation` framework (which is good for startup performance). The biggest problem with doing this would be if it lead to App Store rejections. After doing a bunch of research on this, while [it did happen once in 2009](https://blog.unity.com/engine-platform/unity-app-store-submissions-problem-solved), I find it fairly unlikely to happen nowadays, especially considering that Apple has later _added_ `crt_externs.h` to the iOS/tvOS/watchOS/visionOS SDKs, strongly signifying the functions therein is indeed supported on those platforms (even though they lack an availability attribute). That we've been overly cautious here has also been noted by `@thomcc` in rust-lang#117910 (comment). r? `@workingjubilee` `@rustbot` label O-apple
Weirdly, I think think this uncovered a bug with the |
…workingjubilee Make more of the test suite run on Mac Catalyst Combined with rust-lang#125225, the only failing parts of the test suite are in `tests/rustdoc-js`, `tests/rustdoc-js-std` and `tests/debuginfo`. Tested with: ```console ./x test --target=aarch64-apple-ios-macabi library/std ./x test --target=aarch64-apple-ios-macabi --skip=tests/rustdoc-js --skip=tests/rustdoc-js-std --skip=tests/debuginfo tests ``` Will probably put up a PR later to enable _running_ on (not just compiling for) Mac Catalyst in CI, though not sure where exactly I should do so? `src/ci/github-actions/jobs.yml`? Note that I've deliberately _not_ enabled stack overflow handlers on iOS/tvOS/watchOS/visionOS (see rust-lang#25872), but rather just skipped those tests, as it uses quite a few APIs that I'd be weary about getting rejected by the App Store (note that Swift doesn't do it on those platforms either). r? `@workingjubilee` CC `@thomcc` `@rustbot` label O-ios O-apple
…workingjubilee Make more of the test suite run on Mac Catalyst Combined with rust-lang#125225, the only failing parts of the test suite are in `tests/rustdoc-js`, `tests/rustdoc-js-std` and `tests/debuginfo`. Tested with: ```console ./x test --target=aarch64-apple-ios-macabi library/std ./x test --target=aarch64-apple-ios-macabi --skip=tests/rustdoc-js --skip=tests/rustdoc-js-std --skip=tests/debuginfo tests ``` Will probably put up a PR later to enable _running_ on (not just compiling for) Mac Catalyst in CI, though not sure where exactly I should do so? `src/ci/github-actions/jobs.yml`? Note that I've deliberately _not_ enabled stack overflow handlers on iOS/tvOS/watchOS/visionOS (see rust-lang#25872), but rather just skipped those tests, as it uses quite a few APIs that I'd be weary about getting rejected by the App Store (note that Swift doesn't do it on those platforms either). r? ``@workingjubilee`` CC ``@thomcc`` ``@rustbot`` label O-ios O-apple
Rollup merge of rust-lang#125226 - madsmtm:fix-mac-catalyst-tests, r=workingjubilee Make more of the test suite run on Mac Catalyst Combined with rust-lang#125225, the only failing parts of the test suite are in `tests/rustdoc-js`, `tests/rustdoc-js-std` and `tests/debuginfo`. Tested with: ```console ./x test --target=aarch64-apple-ios-macabi library/std ./x test --target=aarch64-apple-ios-macabi --skip=tests/rustdoc-js --skip=tests/rustdoc-js-std --skip=tests/debuginfo tests ``` Will probably put up a PR later to enable _running_ on (not just compiling for) Mac Catalyst in CI, though not sure where exactly I should do so? `src/ci/github-actions/jobs.yml`? Note that I've deliberately _not_ enabled stack overflow handlers on iOS/tvOS/watchOS/visionOS (see rust-lang#25872), but rather just skipped those tests, as it uses quite a few APIs that I'd be weary about getting rejected by the App Store (note that Swift doesn't do it on those platforms either). r? ``@workingjubilee`` CC ``@thomcc`` ``@rustbot`` label O-ios O-apple
…bilee Make more of the test suite run on Mac Catalyst Combined with rust-lang/rust#125225, the only failing parts of the test suite are in `tests/rustdoc-js`, `tests/rustdoc-js-std` and `tests/debuginfo`. Tested with: ```console ./x test --target=aarch64-apple-ios-macabi library/std ./x test --target=aarch64-apple-ios-macabi --skip=tests/rustdoc-js --skip=tests/rustdoc-js-std --skip=tests/debuginfo tests ``` Will probably put up a PR later to enable _running_ on (not just compiling for) Mac Catalyst in CI, though not sure where exactly I should do so? `src/ci/github-actions/jobs.yml`? Note that I've deliberately _not_ enabled stack overflow handlers on iOS/tvOS/watchOS/visionOS (see rust-lang/rust#25872), but rather just skipped those tests, as it uses quite a few APIs that I'd be weary about getting rejected by the App Store (note that Swift doesn't do it on those platforms either). r? ``@workingjubilee`` CC ``@thomcc`` ``@rustbot`` label O-ios O-apple
Use
_NSGetEnviron
,_NSGetArgc
and_NSGetArgv
on iOS/tvOS/watchOS/visionOS, see each commit and the code comments for details. This allows us to unify more code with the macOS implementation, as well as avoiding linking to theFoundation
framework (which is good for startup performance).The biggest problem with doing this would be if it lead to App Store rejections. After doing a bunch of research on this, while it did happen once in 2009, I find it fairly unlikely to happen nowadays, especially considering that Apple has later added
crt_externs.h
to the iOS/tvOS/watchOS/visionOS SDKs, strongly signifying the functions therein is indeed supported on those platforms (even though they lack an availability attribute).That we've been overly cautious here has also been noted by @thomcc in #117910 (comment).
r? @workingjubilee
@rustbot label O-apple