dotnet / runtime

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

Multiple Jit compile errors on net6-ios target #72342

Open TonyHoyle opened 2 years ago

TonyHoyle commented 2 years ago

Description

I have been trying to update our project to net6 from xamarin. Most platforms, no issues, although I had to use the preview visual studio to get the Maui Essentials library.

iOS has been a nightmare.. hence my posting on a Sunday evening!

Reproduction Steps

Calling FileSystem.AppDataDirectory within FinishedLaunching causes an 'Attempting to JIT compile method' error. Curiously it works fine if you call it before UIApplication.Main, but not later. Since it's one of the reasons we used Xamarin.Essentials and now the Maui essentials, it's a bit of a pain (ended up passing it in a global variable).

Almost anything involving dynamics breaks.. for example the following line:

if (refValue == null)
    stuff.

Blows up with an AOT error whether refValue is defined as a dynamic or a dynamic?

But

if(refValue is null)
  stuff

Works??

Also any call to GetType() on a dynamic fails similarly. Can mostly replace them with 'is' but surely it's doing the same thing underneath anyway..

Eventually I gave up and replaced every reference to dynamic with object.. which 'solved' the problem for a few hours work.

The following line throws up an invalid cast on iOS but not any other platform:

decimal discountPercent = (decimal)(GlobalDetailPersister.GetValueForGlobalDetail(GlobalDetailPersister.CDiscount) ?? 0);

It seems the ?? operator isn't firing (the result from the function call is null when it fails). Breaking it up into several lines works around it.

This one has me stumped.. it blows up with an AOT error. It's just calling an OpenTK function with a constant value.

GL.Enable(EnableCap.DepthTest);

Since this last one can't be worked around - we have several hundred such calls - I've rolled back to xamarin.ios now until things are more stable..

I also tried with UseInterpreter set to true but that just made the app quit silently with no errors immediately after leaving FinishedLaunching, so that's a dead end..

Repro project from https://github.com/dotnet/runtime/issues/72342#issuecomment-1189621472:

Dynamic test.zip - make sure to build in Release config

Expected behavior

It should be possible to compile code that works on net6-android, xamarin-ios etc. without major changes and definitely without random explosions.

Actual behavior

Random crashes, as above.

Regression?

This is a regression as it worked on xamarin.ios

Known Workarounds

No response

Configuration

Visual studio 17..0 preview 3.0 dotnet 6.0.400-preview.22330.6

Compiling for net6-ios on arm64

Other information

No response

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

marek-safar commented 2 years ago

Could you please share entire error message?

ghost commented 2 years ago

Tagging subscribers to 'os-ios': @steveisok, @akoeplinger See info in area-owners.md if you want to be subscribed.

Issue Details
### Description I have been trying to update our project to net6 from xamarin. Most platforms, no issues, although I had to use the preview visual studio to get the Maui Essentials library. iOS has been a nightmare.. hence my posting on a Sunday evening! ### Reproduction Steps Calling FileSystem.AppDataDirectory within FinishedLaunching causes an 'Attempting to JIT compile method' error. Curiously it works fine if you call it before UIApplication.Main, but not later. Since it's one of the reasons we used Xamarin.Essentials and now the Maui essentials, it's a bit of a pain (ended up passing it in a global variable). Almost anything involving dynamics breaks.. for example the following line: ``` if (refValue == null) stuff. ``` Blows up with an AOT error whether refValue is defined as a dynamic or a dynamic? But ``` if(refValue is null) stuff ``` Works?? Also any call to GetType() on a dynamic fails similarly. Can mostly replace them with 'is' but surely it's doing the same thing underneath anyway.. Eventually I gave up and replaced every reference to dynamic with object.. which 'solved' the problem for a few hours work. The following line throws up an invalid cast on iOS but not any other platform: ` decimal discountPercent = (decimal)(GlobalDetailPersister.GetValueForGlobalDetail(GlobalDetailPersister.CDiscount) ?? 0);` It seems the ?? operator isn't firing (the result from the function call is null when it fails). Breaking it up into several lines works around it. This one has me stumped.. it blows up with an AOT error. It's just calling an OpenTK function with a constant value. ` GL.Enable(EnableCap.DepthTest); ` Since this last one can't be worked around - we have several hundred such calls - I've rolled back to xamarin.ios now until things are more stable.. I also tried with UseInterpreter set to true but that just made the app quit silently with no errors immediately after leaving FinishedLaunching, so that's a dead end.. ### Expected behavior It should be possible to compile code that works on net6-android, xamarin-ios etc. without major changes and definitely without random explosions. ### Actual behavior Random crashes, as above. ### Regression? This is a regression as it worked on xamarin.ios ### Known Workarounds _No response_ ### Configuration Visual studio 17..0 preview 3.0 dotnet 6.0.400-preview.22330.6 Compiling for net6-ios on arm64 ### Other information _No response_
Author: TonyHoyle
Assignees: -
Labels: `untriaged`, `area-Codegen-JIT-mono`, `os-ios`
Milestone: -
TonyHoyle commented 2 years ago

Sure.. will repeat the errors and post the full message - may not be today though.

Tony

On Mon, Jul 18, 2022 at 4:03 PM msftbot[bot] @.***> wrote:

Tagging subscribers to 'os-ios': @steveisok https://github.com/steveisok, @akoeplinger https://github.com/akoeplinger See info in area-owners.md if you want to be subscribed. Issue Details

Description

I have been trying to update our project to net6 from xamarin. Most platforms, no issues, although I had to use the preview visual studio to get the Maui Essentials library.

iOS has been a nightmare.. hence my posting on a Sunday evening! Reproduction Steps

Calling FileSystem.AppDataDirectory within FinishedLaunching causes an 'Attempting to JIT compile method' error. Curiously it works fine if you call it before UIApplication.Main, but not later. Since it's one of the reasons we used Xamarin.Essentials and now the Maui essentials, it's a bit of a pain (ended up passing it in a global variable).

Almost anything involving dynamics breaks.. for example the following line:

if (refValue == null) stuff.

Blows up with an AOT error whether refValue is defined as a dynamic or a dynamic?

But

if(refValue is null) stuff

Works??

Also any call to GetType() on a dynamic fails similarly. Can mostly replace them with 'is' but surely it's doing the same thing underneath anyway..

Eventually I gave up and replaced every reference to dynamic with object.. which 'solved' the problem for a few hours work.

The following line throws up an invalid cast on iOS but not any other platform:

decimal discountPercent = (decimal)(GlobalDetailPersister.GetValueForGlobalDetail(GlobalDetailPersister.CDiscount) ?? 0);

It seems the ?? operator isn't firing (the result from the function call is null when it fails). Breaking it up into several lines works around it.

This one has me stumped.. it blows up with an AOT error. It's just calling an OpenTK function with a constant value.

GL.Enable(EnableCap.DepthTest);

Since this last one can't be worked around - we have several hundred such calls - I've rolled back to xamarin.ios now until things are more stable..

I also tried with UseInterpreter set to true but that just made the app quit silently with no errors immediately after leaving FinishedLaunching, so that's a dead end.. Expected behavior

It should be possible to compile code that works on net6-android, xamarin-ios etc. without major changes and definitely without random explosions. Actual behavior

Random crashes, as above. Regression?

This is a regression as it worked on xamarin.ios Known Workarounds

No response Configuration

Visual studio 17..0 preview 3.0 dotnet 6.0.400-preview.22330.6

Compiling for net6-ios on arm64 Other information

No response Author: TonyHoyle Assignees: - Labels:

untriaged, area-Codegen-JIT-mono, os-ios Milestone: -

— Reply to this email directly, view it on GitHub https://github.com/dotnet/runtime/issues/72342#issuecomment-1187612156, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACALFJPHVMPLVEGDODQGQTVUVW3HANCNFSM532H4QIQ . You are receiving this because you authored the thread.Message ID: @.***>

TonyHoyle commented 2 years ago

1.

OK with some attempts at replication it's any function that contains FileSystem.AppDataDirectory. No crash dump, just an error message and the entire application terminates.

System.ExecutionEngineException Message=Attempting to JIT compile method 'System.IO.Stream Shared.iOS.IOSResourceManager:OpenDataFile (string,bool)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

The line that failed here is:

            var savedDataStream =

_resourceManager.OpenDataFile("HippoConfig.json", false);

and OpenDataFile is just:

   public Stream OpenDataFile(string filename, bool write)
    {
        if (write)
            return

File.OpenWrite(Path.Combine(FileSystem.AppDataDirectory, filename)); else return File.OpenRead(Path.Combine(FileSystem.AppDataDirectory, filename)); }

Note that the application does not enter the routine - a breakpoint on the first line is not hit - simply attempting to call it is enough. Removing the FileSystem.AppDataDirectory call removes the error, and the breakpoint is hit.. it seems it is in fact attempting to JIT compile that routine and fails.

Interestingly, and this is something I didn't try yesterday putting a dummy call..

var foo = FileSystem.AppDataDirectory;

In the main Application seems fix this.. something I somehow didn't try yesterday. Is there some kind of init function I should be calling for Maui.Essentials? Nothing in the documentation I can see..

2.

This is the error for the dynamic stuff..

System.ExecutionEngineException Message=Attempting to JIT compile method '(wrapper dynamic-method) void object:Thunk1_CallSite_DesignerMenu_String_Object_String (System.Func`2<object[], object>,System.Runtime.CompilerServices.CallSite,RpsApp.Core.Customisation.DesignerMenu,string,object,string)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

And the line that failed:

                AddDefault(item.Tag, def, item.Tag);

item.Tag is just a string, so likely not an issue. def is a dynamic. AddDefault is simply:

    private void AddDefault(string Tag, string Value, string Parent)
    {
       ...

Dynamic should handle an implicit cast . that being one of the primary reasons it was used so much in the code.

Changing to:

                AddDefault(item.Tag, (string)def, item.Tag);

'fixes' that one.

System.ExecutionEngineException Message=Attempting to JIT compile method '(wrapper dynamic-method) object object:Thunk1ret_Object_CallSite_Object_Object (System.Func`2<object[], object>,System.Runtime.CompilerServices.CallSite,object,object)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

This on is simply on:

if (refValue == null)

Where refValue is a dynamic that is (currently) null.

Replacing with

if(refValue is null)

works around the issue, however it then fails a few lines further down when it hits a non-null case..

System.ExecutionEngineException Message=Attempting to JIT compile method '(wrapper dynamic-method) object object:Thunk1ret_Object_CallSite_Object_Type (System.Func`2<object[], object>,System.Runtime.CompilerServices.CallSite,object,System.Type)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

This fails here:

 if (refValue.GetType() == typeof(int) &&

Common.LengthToMM(menuItem.Value, out temp))

In fact any call to GetType() fails.

I haven't got time today to strip out the dynamics to get as far as the other errors.. it's rather complex to do and I ditched that branch...

steveisok commented 2 years ago

@rolfbjarne bringing you in as there may be things that are more XI specific.

@TonyHoyle Do you have a sample project we could try out?

TonyHoyle commented 2 years ago

It's probably possible to make a minimal repro out of what we have... Will see what I can do.

On Mon, Jul 18, 2022 at 8:09 PM Steve Pfister @.***> wrote:

@rolfbjarne https://github.com/rolfbjarne bringing you in as there may be things that are more XI specific.

@TonyHoyle https://github.com/TonyHoyle Do you have a sample project we could try out?

— Reply to this email directly, view it on GitHub https://github.com/dotnet/runtime/issues/72342#issuecomment-1188154597, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACALFKSWNY6FAFQMT3AU63VUWTVBANCNFSM532H4QIQ . You are receiving this because you were mentioned.Message ID: @.***>

TonyHoyle commented 2 years ago

OK I couldn't get the first bit with AppDataDirectory to repeat on a simple repro - but since the workaround is simply to refer to it in the ApplicationMain it's the lowest priority anyway.

The dynamics though.. In TestAppDelegate there's DynamicCrash1 and DynamicCrash2, showing passing a dynamic parameter and comparing with null. Both crash with an AOT error. This is a far more serious error as it makes the ios builds of any project that uses dynamics unusable.

Dynamic test.zip

steveisok commented 2 years ago

@vargaz How well is dynamic supported in AOT? And perhaps mono in general since we came over to dotnet/runtime?

vargaz commented 2 years ago

Its not very well tested, it probably requires interpreter support.

akoeplinger commented 2 years ago

I can reproduce the dynamics issue with the test project. Given we're running out of time in 7.0 I'm moving the milestone to 8.0 but we should investigate this soon so we can backport fixes to 7.0 (and maybe 6.0).