-
Notifications
You must be signed in to change notification settings - Fork 4.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
Dependency on System.Runtime.InteropServices.RuntimeInformation causes runtime error for apps targeting net451 on *nix systems (i.e. running on Mono) #17471
Comments
@JunTaoLuo could you upgrade to CoreFX rc3-24128-00 / Microsoft.NetCore.App 1.0.0-rc3-004338 / CLI 1.0.0-preview2-002911 and report back? |
I suspect this will still be happening on the latest packages. BTW, it looks like the issue is with System.Runtime.InteropServices.RuntimeInformation, rather than System.Runtime.InteropServices. We have a |
Updated the title and assignee. This isn't for Interop, it's RuntimeInformation. I would expect some different results using the latest packages, since those will probably result in the desktop implementation being chosen. Not much we can do in packaging here since Mono pretends to be desktop and doesn't use a RID. We could make the desktop library try to p-inoke to some *nix APIs (directly, without shim) if it didn't find the Windows ones. Not sure how folks feel about that. |
I still see the same error with the latest packages. |
@ellismg is going to take a look |
https://github.com/dotnet/cli/issues/3350 is a CLI problem that is causing a unix asset to be deployed instead of the Windows one. Even if we deploy the correct asset, we still end up with p/invokes into kernel32 (which won't work) but we'd at least be able to provide some light-up mono implementation via late-binding. |
btw., same on mono 4.5.2.372 on Ubuntu 14.04, targeting Is there some workaround we can use? |
I confirm that by using a separately built System.Native, I could get the RuntimeInformation class to work on Mono on both x86 and x64 Ubuntu 16.04. It is a matter of shipping those libraries as source/binaries for the architectures that mono supports. |
@ericstj The .NET CLI includes a RuntimeInformation class that detects Windows vs. *nix cases and P/Invokes straight thru to the native syscalls. I confirm that, that code cross-compiles and works fine unmodified on Linux/Mono: https://github.com/dotnet/cli/tree/rel/1.0.0/src/Microsoft.DotNet.InternalAbstractions/Native |
@borgdylan that's already understood. As @ellismg mentioned we need to decide how we want to do that since mono represents itself as .NET desktop WRT to NuGet. |
The way the CLI internal abstractions work would be best. That code works ok irrespective of CLR and treats operating systems directly. The alternative would be to make mono use parts of System.Native and friends as part of its codebase so that APIs new in corefx and not present in mono would just work. That would open up prospects of using mono's core parts i.e its CLR as a CoreCLR stand-in on platforms where the CoreCLR does not run in order to run apps that target corefx. Example platforms are Linux x86, LInux on MIPS, Linux on PowerPC. |
The latter case would need cooperation from the Xamarin team. |
Yep that's what we're thinking to do for this particular case. We'll make the desktop implementation of this contract "work" on Mono and give some meaningful results without relying on p-invokes to a native shim we cannot deploy. I suspect we'll do some reflection lightup to detect it's mono then call some mono APIs that provide similar information. That's what @ellismg meant by late binding. I don't think we want to have the native shims become something that's part of Mono. They are too brittle. |
@ericstj The reflection based search for |
Yep, the other thing we need is an implementation of this for Mono, ideally without any PInvokes. Perhaps we can translate mono's |
First of all due to how full framework behaves, Mono will not distinguish between Linux and Mac in the Environment APIs. Both will be reported as |
A per before, you can distinguish 32 and 64 bit but not whether it is ARM/Intel/MIPS/PowerPC. |
The OS version will be the Linux kernel version. (in the Linux case) |
Therefore this cannot be done using pure Mono/.NET without P/Invokes. There is a reason why System.Native was used for CoreCLR. The only way to make this API run perfect is to have native implementation libraries on all three CLRs or to have all three CLRs ship a runtime info file or use an RID. |
The code in: https://github.com/dotnet/cli/blob/rel/1.0.0/src/Microsoft.DotNet.InternalAbstractions/Native/PlatformApis.cs solves part of the problem but requires IO and P/Invokes. |
The code in: https://github.com/dotnet/cli/blob/rel/1.0.0/src/Microsoft.DotNet.InternalAbstractions/RuntimeEnvironment.cs reiterates the fact that you cannot distinguish Intel/ARM/MIPS/PowerPc. Mono supports a host of architectures and you cannot get it right without the System.Native port to all those architectures. |
@ericstj Do remember that Mono means Xamarin which means MSFT. I do see a world where .NET and mono teams collaborate to have a subset of System.Native be present in Mono and be compatible with the CoreCLR version. |
@borgdylan I'm not arguing here, nor do I disagree with anything that's been said around mono support. I am sorry if that's how this is coming off, but that's the last thing on my mind. I want to support mono and I want to do so with minimal coupling. I'm just stating the constraints we have and discussing possible design choices.
Shims don't solve the processor architecture problem, they just push it to NuGet. The shims hardcode the architecture value and NuGet uses RID to give us the shim with the right hardcoded value. I'd like to keep the goal of not having mono projects require a RID. Which I understand is why you are suggesting:
/cc @stephentoub @jkotas @davidfowl The main reason we have shims was to avoid many forks of the IL per-distro/version, initially we were doing all the translation in IL and directly PInvoking to the *nix OS. I suspect there is a way to do so here, we just need someone more knowledgeable in *nix than myself to do a deep dive. I think @ellismg already has an idea here so I'd like to wait for his feedback, especially since this issue is assigned to him, before we go further down the path of trying to design this. |
I'll try once I arrive at work. It's 7:30 am here. |
So the PR got accepted. I will make a new branch with the standalone build based on the PR and @jkotas 's feedback on the current version. |
@jkotas @Tragetaschen @ericstj The new standalone stuff will be done here: https://github.com/borgdylan/corefx/commits/sysnative_standalone2 |
With my latest round of testing I can conclude that the library built by the standalone and normal build systems lead to the same behaviour of the S.R.IS.RI API under mono. |
For anyone looking for a workaround (on macOS/Darwin at least), here are some notes on getting things working on OS X (and in theory they should work on Ubuntu with little or no modification, but I haven't tested):
NotesRegardless of your choice in Step 3, only When the above doesn't work, I've also found it helpful to run |
Btw., for the case of the missing System.Native library, aspnet/KestrelHttpServer#963 (comment) provides a workaround. I managed to get |
@DustinCampbell Desktop != Mono. The desktop C# compiler package is meant to run on desktop. If you run app build for desktop on Mono, your mileage will vary. That's by design. |
@jkotas I thought the point of "netstandard" was that it would allow people to build different runtimes targeting the same standard. If Mono is an implementation of "net46" how can it not be expected to be compatible with netstandard libraries compiled against "net46"? |
That's true but this package should be made to work on mono. @emgarten do we have a mono TFM as yet? If not, we can just do some runtime light up. |
Yes, mono TFM is the proper "correct by construction" solution for this problem. |
agreed -- for many things. The Microsoft.Build.Runtime package would benefit greatly from that TFM as well |
Maybe for some things. But that abandons the notion that Mono is an alternate implementation of some/most of net46 -- which is its entire purpose today. If you abandon that design, you are leaving behind almost all of Mono's consumers. |
there is no mono TFM in NuGet currently |
Mono has played catch up game to make the cross-platform subset of desktop APIs work. If you want to take advantage of it for your app, you have to be careful to only depend on what it has caught up with. It has not caught up with System.Runtime.InteropServices.RuntimeInformation yet. There is a proposed PR to fix that: mono/mono#4234. Once it goes through, the particular problem with S.R.InteropServices.RuntimeInformation will be solved. |
That's not true, we've been shipping an implementation for that in Mono 4.6. The issue is that the System.Runtime.InteropServices.RuntimeInformation nuget package contains an implementation in the lib\net45 folder which will be copied to the app directory and since it calls into Windows APIs it'll crash on other platforms. Mono prefers loading an assembly from the app directory, that's why the GAC version is not getting used. The PR you mentioned above works around that problem by blacklisting assemblies which we know to be broken on Mono, which is hardly a perfect solution. We're discussing the larger issue at https://github.com/dotnet/corefx/issues/15112 and should probably continue the discussion there. |
Agree. I should have been more specific - Mono has not caught up yet with how System.Runtime.InteropServices.RuntimeInformation and similar OOB packages are deployed in desktop apps. |
@akoeplinger what version of mono is going to fix this? |
@davidfowl we shipped a "fix" with Mono 4.8 which essentially blacklists some specific assemblies+versions like SRI.RuntimeInformation: https://github.com/mono/mono/blob/mono-4.8.0-branch/mono/metadata/image.c#L1035-L1091 A more future-proof solution is currently being discussed in dotnet/corefx#15112 |
For what it's worth, even with Mono 5.4 I still have to symlink |
Scenario
net451
app depending onSystem.Runtime.InteropServices.RuntimeInformation
on OSX/Ubuntu will produce the following exception at runtime:Example
See repro at https://github.com/JunTaoLuo/RuntimeServiceOnMono. To run the sample, run
dotnet restore
anddotnet run -f net451
I understand Mono is not a scenario that's actively being developed for but we should not be causing a exception like this especially since we intend to use the
InteropServices
APIs in often used ASP.NET packages like Logging.Currently this means that most of our samples and apps cannot run on Mono (full CLR on *nix).
Environment
dotnet --version
:mono -V
:cc @BrennanConroy @muratg @Eilon
The text was updated successfully, but these errors were encountered: