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

Implement Environment.GetEnvironmentVariables for Apple platforms using official API on iOS/tvOS/MacCatalyst #58161

Merged
merged 11 commits into from
Aug 27, 2021

Conversation

filipnavara
Copy link
Member

@filipnavara filipnavara commented Aug 26, 2021

Fixes #58156

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Aug 26, 2021
@ghost
Copy link

ghost commented Aug 26, 2021

Tagging subscribers to this area:
See info in area-owners.md if you want to be subscribed.

Issue Details

Not for review yet, only trying CI

Author: filipnavara
Assignees: -
Labels:

area-VM-meta-mono

Milestone: -

@@ -97,22 +89,57 @@ private static void EnsureEnvironmentCached()
{
var results = new Dictionary<string, string>();

foreach (string name in GetEnvironmentVariableNames())
IntPtr block = Interop.Sys.GetEnviron();
Copy link
Member Author

Choose a reason for hiding this comment

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

This code is straight copy from NativeAOT.

Copy link
Contributor

Choose a reason for hiding this comment

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

then I think it would be better to have it in shared location

Copy link
Member Author

Choose a reason for hiding this comment

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

Generally I would agree.

I started with a minimal fix because I wanted to limit the impact for backporting to .NET 6 branch.

Then I moved it to System.Native based on chat with @akoeplinger (and I agree that it belongs there). Proper sharing of the code with NativeAOT will need few more changes and I wanted to validate the approach first before proceeding with that.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think this is fine for now, we can unify with NativeAOT in main later on.

@filipnavara filipnavara changed the title Implement mono_icall_get_environment_variable_names for Apple platforms using official API Implement Environement.GetEnvironmentVariables for Apple platforms using official API Aug 26, 2021
@filipnavara filipnavara marked this pull request as ready for review August 26, 2021 12:20
@filipnavara
Copy link
Member Author

cc @jkotas This will inevitably clash with NativeAOT. Ideally we'd want to share parts of the code but I am waiting for some feedback about the approach first. It may need to be backported to .NET 6 branch.

@filipnavara filipnavara changed the title Implement Environement.GetEnvironmentVariables for Apple platforms using official API Implement Environment.GetEnvironmentVariables for Apple platforms using official API Aug 26, 2021
@jkotas
Copy link
Member

jkotas commented Aug 26, 2021

cc @jkotas This will inevitably clash with NativeAOT

No worries. It is easy to fixup conflicts like this one.

src/mono/mono/mini/CMakeLists.txt Outdated Show resolved Hide resolved
src/mono/mono/metadata/icall.c Outdated Show resolved Hide resolved
@@ -97,22 +89,57 @@ private static void EnsureEnvironmentCached()
{
var results = new Dictionary<string, string>();

foreach (string name in GetEnvironmentVariableNames())
IntPtr block = Interop.Sys.GetEnviron();
Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think this is fine for now, we can unify with NativeAOT in main later on.

src/libraries/Native/Unix/System.Native/CMakeLists.txt Outdated Show resolved Hide resolved
src/libraries/Native/Unix/System.Native/CMakeLists.txt Outdated Show resolved Hide resolved
src/libraries/Native/Unix/System.Native/pal_environment.m Outdated Show resolved Hide resolved
src/libraries/Native/Unix/System.Native/pal_environment.m Outdated Show resolved Hide resolved
@jkotas
Copy link
Member

jkotas commented Aug 26, 2021

remove HAVE_NSGETENVIRON

Why not use it when it is available and avoid the memory leak from the other solution?

@filipnavara
Copy link
Member Author

Why not use it when it is available and avoid the memory leak from the other solution?

_NSGetEnviron is not a public API. It used to fail App Store submissions in past and it's not even in the public headers (anymore? maybe on ARM64 only?).

@jkotas
Copy link
Member

jkotas commented Aug 26, 2021

_NSGetEnviron is not a public API

It is not a public API on Apple device OSes, but I believe that it is de-facto public API on Apple desktop OSes.

@filipnavara
Copy link
Member Author

It is not a public API on Apple device OSes, but I believe that it is de-facto public API on Apple desktop OSes.

You are right, it seems to exist on the desktop headers. I incorrectly based the assumption on a 14-year old comment in the Mono code (https://github.com/dotnet/runtime/blame/3f61d42cdfc65cfa1822986a9d257f1558545c4d/src/mono/mono/metadata/icall.c#L6273-L6276).

@vargaz
Copy link
Contributor

vargaz commented Aug 27, 2021

Is it useful for ios apps to read their native environment ? Apple generally doesn't like it for security reasons, thats why a lot of these apis were removed. Wouldn't be better to return just the env variables defined by the user/set during the build ?

@filipnavara
Copy link
Member Author

filipnavara commented Aug 27, 2021

Is it useful for ios apps to read their native environment?

In some cases it is. There are some global variables like HOME that .NET uses (and so did mono/mono). It is also useful for diagnostics and for reading variables that were set through PList files inside the app, or through mlaunch or other external tools.

I would find it highly inconsistent that GetEnvironmentVariable returns something and GetEnvironmentVariables does not which is how legacy Mono behaved.

@filipnavara
Copy link
Member Author

filipnavara commented Aug 27, 2021

Apple generally doesn't like it for security reasons, thats why a lot of these apis were removed.

I am not sure that is the reason for the removal. _NSGetEnviron is inherently not thread safe and it's exported only to support C runtime. Perhaps Apple just decided not to expose the "broken" API for a different reason. Just like they are now trying to push people away from BSD socket API into their own Network.framework.

[[NSProcessInfo processInfo] environment] has been public API since the beginning (iOS 2) and it is not deprecated. That's in stark contrast to _NSGetEnviron which was never a public API on the device platforms to begin with. If Apple wanted to restrict access to environment variables they can easily return empty or filtered dictionaries in the public APIs (not so easy with _NSGetEnviron which exposes some internal structure details).

Wouldn't be better to return just the env variables defined by the user/set during the build ?

There's too many ways to set the environment variables (Info.plist files, simctl tool, mlaunch tool, ios-deploy tool) that trying to emulate it would be poor approximation. I don't think it makes sense if there is public API available. Setting these environment variables may not be important for release workflows but it's one of the few ways that are universally available for passing options for both on-device and simulator diagnostics. It also makes a lot of sense for developer scenarios like unit tests and benchmarks where the filtering options are passed through environment variables [and which are deployed using different tools based on a workflow and device setup]. Aside from the application variables there are few global variables that may be useful (HOME, LOCALE, LANGUAGE, etc.) and which are queried by existing code.

@akoeplinger akoeplinger merged commit 3e8e0b8 into dotnet:main Aug 27, 2021
@akoeplinger akoeplinger changed the title Implement Environment.GetEnvironmentVariables for Apple platforms using official API Implement Environment.GetEnvironmentVariables for Apple platforms using official API on iOS/tvOS/MacCatalyst Aug 27, 2021
@akoeplinger
Copy link
Member

/backport to release/6.0

@github-actions
Copy link
Contributor

Started backporting to release/6.0: https://github.com/dotnet/runtime/actions/runs/1173975336

@github-actions
Copy link
Contributor

@akoeplinger backporting to release/6.0 failed, the patch most likely resulted in conflicts:

$ git am --3way --ignore-whitespace --keep-non-patch changes.patch

Applying: Implement mono_icall_get_environment_variable_names for Apple platforms using official API
Using index info to reconstruct a base tree...
M	src/mono/mono/metadata/icall.c
Falling back to patching base and 3-way merge...
Auto-merging src/mono/mono/metadata/icall.c
CONFLICT (content): Merge conflict in src/mono/mono/metadata/icall.c
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Implement mono_icall_get_environment_variable_names for Apple platforms using official API
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

akoeplinger added a commit to akoeplinger/runtime that referenced this pull request Aug 27, 2021
…ng official API (dotnet#58161)

Move environment handling from Mono runtime to System.Native

Fixes dotnet#58156

Co-authored-by: Alexander Köplinger <[email protected]>
Co-authored-by: Adeel Mujahid <[email protected]>
akoeplinger added a commit that referenced this pull request Aug 27, 2021
…ng official API (#58161) (#58254)

Move environment handling from Mono runtime to System.Native

Fixes #58156

Co-authored-by: Filip Navara <[email protected]>
Co-authored-by: Adeel Mujahid <[email protected]>
@ghost ghost locked as resolved and limited conversation to collaborators Sep 26, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Runtime.InteropServices community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using GetEnvironmentVariables wipes all envvars
8 participants