dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.06k stars 4.69k forks source link

Mono on none Windows platforms cache environment variables in managed code when changed. #51019

Open lateralusX opened 3 years ago

lateralusX commented 3 years ago

On none Windows platforms, Mono S.P.C will take a copy of processs environment block when SetEnvironmentVariable gets called:

https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/mono/System.Private.CoreLib/src/System/Environment.Unix.Mono.cs#L42

after that managed and native copies will diverge, and native runtime will not see changes done by managed code (and the other way around).

On Windows this works as expected since we use:

https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.Private.CoreLib/src/System/Environment.Variables.Windows.cs#L33

that ends up in underlying OS functions (same as on CoreClr), same API's accessed by native runtime.

This works better on CoreClr on none Windows platforms since it uses the Environment.Variables.Windows.cs calling into the CoreClr native PAL and other native runtime code will access environment using the same PAL functions, meaning that all CoreClr native runtime code will be in sync with managed code.

This cause issues on an EventPipe runtime test, on none Windows Mono platforms:

https://github.com/dotnet/runtime/tree/main/src/tests/tracing/eventpipe/processenvironment

That tests sets a couple of environment variables in managed code and then expect to get them back over diagnostics server IPC channel (using the same process IPC channel). This fails on Mono on none Windows platforms, since the diagnostics server handling the command is implemented in native code, and due to the above caching, it will never see the environment variables set by the test and fails.

A workaround would be to redesign the test to spawn a separate process hosting the diagnostics server and pass over the environment variables to test when spawning that process.

In order to fix this we would need to do something similar to CoreClr, do caching in low level native PAL layer and make sure all runtime code goes through that layer when working with env variables. This will still create a cached copy, so using raw getenv/setenv/unsetenv etc will still see different results, but all runtime code (managed and native) should call through the PAL giving same view of data and same behaviour as CoreClr.

ghost commented 8 months ago

Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.

Issue Details
On none Windows platforms, Mono S.P.C will take a copy of processs environment block when SetEnvironmentVariable gets called: https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/mono/System.Private.CoreLib/src/System/Environment.Unix.Mono.cs#L42 after that managed and native copies will diverge, and native runtime will not see changes done by managed code (and the other way around). On Windows this works as expected since we use: https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.Private.CoreLib/src/System/Environment.Variables.Windows.cs#L33 that ends up in underlying OS functions (same as on CoreClr), same API's accessed by native runtime. This works better on CoreClr on none Windows platforms since it uses the Environment.Variables.Windows.cs calling into the CoreClr native PAL and other native runtime code will access environment using the same PAL functions, meaning that all CoreClr native runtime code will be in sync with managed code. This cause issues on an EventPipe runtime test, on none Windows Mono platforms: https://github.com/dotnet/runtime/tree/main/src/tests/tracing/eventpipe/processenvironment That tests sets a couple of environment variables in managed code and then expect to get them back over diagnostics server IPC channel (using the same process IPC channel). This fails on Mono on none Windows platforms, since the diagnostics server handling the command is implemented in native code, and due to the above caching, it will never see the environment variables set by the test and fails. A workaround would be to redesign the test to spawn a separate process hosting the diagnostics server and pass over the environment variables to test when spawning that process. In order to fix this we would need to do something similar to CoreClr, do caching in low level native PAL layer and make sure all runtime code goes through that layer when working with env variables. This will still create a cached copy, so using raw getenv/setenv/unsetenv etc will still see different results, but all runtime code (managed and native) should call through the PAL giving same view of data and same behaviour as CoreClr.
Author: lateralusX
Assignees: -
Labels: `area-System.Runtime`, `runtime-mono`
Milestone: Future