RichTextKit icon indicating copy to clipboard operation
RichTextKit copied to clipboard

Exception: Attempting to JIT

Open charlenni opened this issue 3 years ago • 34 comments

I get, while using RichTextKit, the following error when calling Layout with FontFamily=null (default for new Font() ) or FontFamily="".

Error Message: "Attempting to JIT compile method 'bool Topten.RichTextKit.FontFallback/<GetFontRuns>d__2:MoveNext ()' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.\n"

StackTrace: at Topten.RichTextKit.TextBlock.AddDirectionalRun (Topten.RichTextKit.StyleRun styleRun, System.Int32 start, System.Int32 length, Topten.RichTextKit.TextDirection direction, Topten.RichTextKit.IStyle style) [0x00057] in <19e5ac464bd84f9c875ac01889614bdc>:0

What did I wrong?

charlenni avatar Mar 08 '21 17:03 charlenni

The exception is is fact a System.ExecutionEngineException.

The full stack trace for RichTextKit is:

  at Topten.RichTextKit.TextBlock.AddDirectionalRun (Topten.RichTextKit.StyleRun styleRun, System.Int32 start, System.Int32 length, Topten.RichTextKit.TextDirection direction, Topten.RichTextKit.IStyle style) [0x00057] in <19e5ac464bd84f9c875ac01889614bdc>:0 
  at Topten.RichTextKit.TextBlock.BuildFontRuns () [0x002e6] in <19e5ac464bd84f9c875ac01889614bdc>:0 
  at Topten.RichTextKit.TextBlock.Layout () [0x000f5] in <19e5ac464bd84f9c875ac01889614bdc>:0 

What did I wrong?

The question is not what you did wrong, but since when this occurs and which change (probably in Xamarin.iOS) triggers it.

I see this with Visual Studio for Mac 8.9 and Xamarin.iOS 14.14.2.5. I assume the problem did not occur with VS for Mac 8.8 (and whatever Xamarin.iOS version it came with), but I'm not completely sure about that.

See Mapsui/Mapsui#1093 for a way to reproduce this.

janusw avatar Mar 09 '21 08:03 janusw

Possibly relevant: https://docs.microsoft.com/en-us/xamarin/ios/troubleshooting/troubleshooting#systemexecutionengineexception-attempting-to-jit-compile-method-wrapper-managed-to-managed-foosystemcollectionsgenericicollection1get_count-

janusw avatar Mar 09 '21 11:03 janusw

Thanks for reporting. Unfortunately I don't have an iOS dev environment setup here (and not keen to set it up just for this one issue).

This seems like an issue with Xamarin AOT more than RichTextKit itself. If someone wants to investigate further and work out a fix for this then I'm happy to merge it.

toptensoftware avatar Mar 10 '21 01:03 toptensoftware

I investigate a little further. With the link @janusw provided (thank you), I would say, the relevant line is 1164 of TextBlock.cs. We get problems with the FontFallback.GetFontRuns(). It seems, that Xamarin.iOS „optimize“ the code, so that it leaves the FontFallback.GetFontRuns(). The suggestion for such a problem is mentioned in the above article: call it by yourself before this line. But I‘m not sure, ho to do this.

Any ideas?

charlenni avatar Mar 10 '21 06:03 charlenni

@janusw Could you try to change the linking of the iOS version. Some users had used „Don‘t link“ to solve this problem.

charlenni avatar Mar 10 '21 06:03 charlenni

@janusw Could you try to change the linking of the iOS version. Some users had used „Don‘t link“ to solve this problem.

Tried to use "Don't link" for Mapsui.Samples.Forms.iOS, but that does not seem to help unfortunately.

janusw avatar Mar 10 '21 08:03 janusw

I investigate a little further. With the link @janusw provided (thank you), I would say, the relevant line is 1164 of TextBlock.cs.

Yes, I think that's the one.

We get problems with the FontFallback.GetFontRuns(). It seems, that Xamarin.iOS „optimize“ the code, so that it leaves the FontFallback.GetFontRuns(). The suggestion for such a problem is mentioned in the above article: call it by yourself before this line. But I‘m not sure, ho to do this.

Any ideas?

I'm not quite sure. Maybe take apart the for loop and call MoveNext explicitly? (I might try that tonight.)

Or maybe the link is not fully to the point, after all. The error message is slightly different.

Btw, which section of https://docs.microsoft.com/en-us/xamarin/ios/internals/limitations do you think is the relevant one here?

janusw avatar Mar 10 '21 08:03 janusw

We get problems with the FontFallback.GetFontRuns(). It seems, that Xamarin.iOS „optimize“ the code, so that it leaves the FontFallback.GetFontRuns(). The suggestion for such a problem is mentioned in the above article: call it by yourself before this line. But I‘m not sure, ho to do this. Any ideas?

I'm not quite sure. Maybe take apart the for loop and call MoveNext explicitly? (I might try that tonight.)

Something like this should do it:

----------------------- Topten.RichTextKit/TextBlock.cs -----------------------
index 5e75472..21f78e7 100644
@@ -1161,9 +1161,11 @@ namespace Topten.RichTextKit
             var codePointsSlice = _codePoints.SubSlice(start, length);
 
             // Split into font fallback runs
-            foreach (var fontRun in FontFallback.GetFontRuns(codePointsSlice, typeface, style.ReplacementCharacter))
+            IEnumerator<FontFallback.Run> runEnum = FontFallback.GetFontRuns(codePointsSlice, typeface, style.ReplacementCharacter).GetEnumerator();
+            while (runEnum.MoveNext())
             {
                 // Add this run
+                var fontRun = runEnum.Current;
                 AddFontRun(styleRun, start + fontRun.Start, fontRun.Length, direction, style, fontRun.Typeface, typeface);
             }
         }

Haven't tried if it helps ...

janusw avatar Mar 10 '21 09:03 janusw

Something like this should do it:

[..]

Haven't tried if it helps ...

AFAICT this does not help, either. I built a nupkg of RichTextKit with that change and used it with Mapsui, but I still get the same error message.

Maybe the usage of iterator blocks in FontFallback.GetFontRuns is the problem (in connection with the limited generics support on iOS)?

janusw avatar Mar 10 '21 09:03 janusw

Maybe it would be useful to add a Xamarin.iOS sample project to the RichTextKit solution, in order to reproduce and debug this problem more easily?

janusw avatar Mar 10 '21 09:03 janusw

As documented in the Mapsui issue (Mapsui/Mapsui#1093), there are similar problems on MacOS as well:

Error: Unexpected error in skia renderer, System.MissingMethodException: Method not found: void SkiaSharp.SKFont.GetGlyphs(System.ReadOnlySpan`1<int>,System.Span`1<uint16>)
  at Topten.RichTextKit.TextBlock.AddDirectionalRun (Topten.RichTextKit.StyleRun styleRun, System.Int32 start, System.Int32 length, Topten.RichTextKit.TextDirection direction, Topten.RichTextKit.IStyle style) [0x00067] in <7a0d8e75b4754a86a12c1b7c67b845cc>:0 
  at Topten.RichTextKit.TextBlock.BuildFontRuns () [0x0032c] in <7a0d8e75b4754a86a12c1b7c67b845cc>:0 
  at Topten.RichTextKit.TextBlock.Layout () [0x0010a] in <7a0d8e75b4754a86a12c1b7c67b845cc>:0 

The error message is quite different here, but the place where the failure occurs is basically the same (FontFallback.GetFontRuns). I assume they're somehow related.

Does anyone have an idea what could cause this kind of error?

janusw avatar Mar 11 '21 14:03 janusw

We are also facing this Problem in an Xamarin.Ios Build for

SIGABRT: Method not found: void SkiaSharp.SKFont.GetGlyphs(System.ReadOnlySpan`1<int>,System.Span`1<uint16>)
TextBlock.AddDirectionalRun (Topten.RichTextKit.StyleRun styleRun, System.Int32 start, System.Int32 length, Topten.RichTextKit.TextDirection direction, Topten.RichTextKit.IStyle style)
TextBlock.BuildFontRuns ()
TextBlock.Layout ()

In Versions:

  • RichTextKit 0.4.138
  • Skia 2.80.2
  • Skia.HarfBuzzsharp 2.80.2

The error exists even if linker is set to none.

The Problem did not occur on older Xamarin Versions with the same library versions. Maybe some Span related errors on the Xamarin side?

slarti-zak avatar Mar 25 '21 06:03 slarti-zak

We are also facing this Problem in an Xamarin.Ios Build for

Good to hear that others get the same error. Do you possibly have a simple reproducer?

janusw avatar Mar 25 '21 10:03 janusw

Any plans on how to proceed on this issue?

pauldendulk avatar Mar 26 '21 15:03 pauldendulk

As mentioned above, I'm not setup for iOS development and busy with other work at the moment. If someone in the community wants to look into it and submit a PR I'll happily merge it.

toptensoftware avatar Mar 28 '21 23:03 toptensoftware

After some more digging, I found https://github.com/xamarin/xamarin-macios/issues/4218, which refers to https://github.com/xamarin/xamarin-macios/issues/3949, where the suggested fix is to migrate to a PackageReference project. Tried this with Mapsui.Samples.Forms.iOS. Didn't help :/

janusw avatar Mar 29 '21 08:03 janusw

Also found: https://stackoverflow.com/questions/12837517/system-executionengineexception-attempting-to-jit-compile-method-only-in-debug/12840169#12840169

This suggests as a workaround to use a reference type instead of a value type, so I tried converting Topten.RichTextKit.FontFallback.Run from a struct to a class:

--------------- Topten.RichTextKit/FontFallback/FontFallback.cs ---------------
index 6210df3..d91f9ce 100644
@@ -30,7 +30,7 @@ namespace Topten.RichTextKit
         /// <summary>
         /// Specified details about a font fallback run
         /// </summary>
-        public struct Run
+        public class Run
         {
             /// <summary>
             /// The starting code point index of this run

But, again, this does not seem to help.

Further tricks for hinting the compiler ("pre-seeding") are played e.g. in https://github.com/SIDOVSKY/EBind/blob/main/EBind/Platform/AotCompilerHints.ios.cs, which links to the above StackOverflow question. See also the comments in https://github.com/SIDOVSKY/EBind#aot-compilation-. I don't really understand the details of what's being done there, but maybe someone else can figure out a fix for our case based on this?

But since my struct-to-class workaround attempt also does not work, maybe our problem still has a different origin? Apparently there can be various reasons why the AOT compiler might fail to generate code ...

janusw avatar Mar 29 '21 09:03 janusw

After all the failed workarounds, I have high hopes that this might actually fix the problem: https://github.com/xamarin/xamarin-macios/pull/10928

Some of the issues referenced there sound very similar to the diagnostics here.

janusw avatar Mar 29 '21 15:03 janusw

I posted a message to Matt Leibowitz (the lead dev on SkiaSharp) about this in case he had any ideas, his response:

Looks like it could be a bug with something in the iOS system. Could you get the folks to report an issue on the xamarin/xamarin-macios repo with a repo if possible. Then the team can have something to track. You can also mark as regression if it was working before.

Source

toptensoftware avatar Mar 31 '21 23:03 toptensoftware

If anyone is interested. I was getting the same exception (not for JIT compilation) but when rendering TextBlocks into a SkiaSharp Canvas.

Method not found: void SkiaSharp.SKFont.GetGlyphs(System.ReadOnlySpan`1<int>,System.Span`1<uint16>)
TextBlock.AddDirectionalRun (Topten.RichTextKit.StyleRun styleRun, System.Int32 start, System.Int32 length, Topten.RichTextKit.TextDirection direction, Topten.RichTextKit.IStyle style)
TextBlock.BuildFontRuns ()
TextBlock.Layout ()

After some investigation I found out that this only happens with the Xamarin.iOS SDK version 14.14.2.5 not on 14.10.0.4 or below. So that's what I used as my workaround.

juanpgarces avatar Apr 06 '21 18:04 juanpgarces

After some investigation I found out that this only happens with the Xamarin.iOS SDK version 14.14.2.5 not on 14.10.0.4 or below.

Yes, this is definitely a regression (see my comments above). Thanks for figuring out a 'good' version.

So that's what I used as my workaround.

How did you do the downgrade? I was not able to find a proper way to downgrade VS for Mac.

janusw avatar Apr 07 '21 08:04 janusw

@janusw, I have not tested this but I think the only way is to uninstall and re-install an older version of VS. For now I was able to just modify the DevOps pipeline in the app building to select the 'good' SDK (I am not currently debugging my app, just needed to fix the buggy deployment).

juanpgarces avatar Apr 07 '21 12:04 juanpgarces

@janusw, I have not tested this but I think the only way is to uninstall and re-install an older version of VS.

Yes, but I don't know where to download an older version. The installer that one gets from the official VS download site will only install the latest version 8.9. The only download of an 'older' VS version that I found is for VS 2017, which is very old.

janusw avatar Apr 07 '21 13:04 janusw

Pleased to hear this isn't an issue with RichTextKit. Has someone reported this to the Xamarin iOS team?

(I'd do it myself except I don't have a repo project as suggested by Matt above).

toptensoftware avatar Apr 07 '21 23:04 toptensoftware

After all the failed workarounds, I have high hopes that this might actually fix the problem: xamarin/xamarin-macios#10928

Today I installed VS for Mac 8.10 Preview (build 967) with Xamarin.iOS 14.17.0.247 and Xamarin.Mac 7.11.0.247, which is supposed to include the fix mentioned above, but unfortunately it looks like my high hopes are being disappointed ...

Regarding iOS, this version seems much worse than before. I'm not able to build any iOS app due to strange errors (System.EntryPointNotFoundException: xamarin_release_managed_ref). So I can not check if the JIT exceptions are gone.

Regarding MacOS, building seems to work well, but I still see the same errors as before (System.MissingMethodException: Method not found: void SkiaSharp.SKFont.GetGlyphs).

😭

janusw avatar Apr 15 '21 08:04 janusw

Today I installed VS for Mac 8.10 Preview (build 967) with Xamarin.iOS 14.17.0.247 and Xamarin.Mac 7.11.0.247, which is supposed to include the fix mentioned above, but unfortunately it looks like my high hopes are being disappointed ...

Regarding iOS, this version seems much worse than before. I'm not able to build any iOS app due to strange errors (System.EntryPointNotFoundException: xamarin_release_managed_ref).

This might be https://github.com/xamarin/xamarin-macios/issues/11151

janusw avatar Apr 15 '21 08:04 janusw

Pleased to hear this isn't an issue with RichTextKit. Has someone reported this to the Xamarin iOS team?

I just did: https://github.com/xamarin/xamarin-macios/issues/11219 (should have done this much earlier, but better late than never!)

janusw avatar Apr 15 '21 11:04 janusw

After all the bad news, finally some good news: I actually managed to find a viable workaround, namely downgrading Xamarin.iOS only (without downgrading VS). Initially I was not sure if this is viable at all, but once you find the download link to the relevant package version, it's actually pretty simple ...

So, I just downloaded https://dl.xamarin.com/MonoTouch/Mac/xamarin.ios-14.10.0.4.pkg (found via homebrew, see also https://github.com/xamarin/xamarin-macios/issues/11218) and installed it on Mac OS. After that, VS for Mac corrently detects the changed version and automatically uses it without any further setup needed.

janusw avatar Apr 15 '21 12:04 janusw

As documented in the Mapsui issue (Mapsui/Mapsui#1093), there are similar problems on MacOS as well:

Error: Unexpected error in skia renderer, System.MissingMethodException: Method not found: void SkiaSharp.SKFont.GetGlyphs(System.ReadOnlySpan`1<int>,System.Span`1<uint16>)
  at Topten.RichTextKit.TextBlock.AddDirectionalRun (Topten.RichTextKit.StyleRun styleRun, System.Int32 start, System.Int32 length, Topten.RichTextKit.TextDirection direction, Topten.RichTextKit.IStyle style) [0x00067] in <7a0d8e75b4754a86a12c1b7c67b845cc>:0 
  at Topten.RichTextKit.TextBlock.BuildFontRuns () [0x0032c] in <7a0d8e75b4754a86a12c1b7c67b845cc>:0 
  at Topten.RichTextKit.TextBlock.Layout () [0x0010a] in <7a0d8e75b4754a86a12c1b7c67b845cc>:0 

The error message is quite different here, but the place where the failure occurs is basically the same (FontFallback.GetFontRuns). I assume they're somehow related.

For the MacOS problem, in contrast to iOS, I was not able to fix it by downgrading Xamarin.Mac, unfortunately ...

janusw avatar Apr 17 '21 08:04 janusw

For the MacOS problem, in contrast to iOS, I was not able to fix it by downgrading Xamarin.Mac, unfortunately ...

To be a bit more precise here: I went as far back as Xamarin.Mac version 6.22.1.16, and that behaves in the same way as the current Xamarin.Mac 7.10.0.5.

I was not able to check earlier versions of Xamarin.Mac (such as 6.20.x and before), because they don't seem to work with the current VS4Mac version 8.9.8. I get the following error during nuget restore:

error MSB4226: The imported project "/Library/Frameworks/Mono.framework/Versions/6.12.0/lib/mono/xbuild/Xamarin/Mac/Xamarin.Mac.CSharp.targets" was not found.
Also, tried to find "Xamarin/Mac/Xamarin.Mac.CSharp.targets" in the fallback search path(s) for $(MSBuildExtensionsPath) - "/Library/Frameworks/Mono.framework/External/xbuild/" and "/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/AddIns/docker/MonoDevelop.Docker/MSbuild" .
These search paths are defined in "/Users/janus/Library/Caches/VisualStudio/8.0/MSBuild/12174_1/MonoDevelop.MSBuildBuilder.exe.config".
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk in one of the search paths.

janusw avatar May 10 '21 07:05 janusw