runtime: [android] arm64 running on x64 emulator unexpected FPSIMD_MAGIC assert

Recent versions (API 30 x86_64) of the Android emultator can run arm64 binaries on an x86_64 emultator using some kind of binary translation. When an app is running in this environment, it looks like the struct sigcontext __reserved field is not laid out with the fpsimd_context first.

As a result this code asserts:

https://github.com/dotnet/runtime/blob/b1b7ad47e2d0bef37fa2fb3b1075cdeabf561c04/src/mono/mono/utils/mono-context.c#L536-L539

Linux kernel sigcontext __reserved note

Instead of looking at the first context in __reserved and asserting that it has FPSIMD_MAGIC, we should check head.magic == FPSIMD_MAGIC and if not, move forward by head.size bytes and try again until we see head.magic == 0 (the last block).

Potentially we can assume that the offset won’t change between calls to mono_sigctx_to_monoctx and cache the pre-computed offset (and assert that the magic is the right one).


Reproduction steps for XA:

  1. Turn off fast deployment by adding <EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk> to the csproj file
  2. Remove definition for $(AndroidSupportedAbis) if there is any in the .csproj file
  3. Add <RuntimeIdentifiers>android-arm;android-arm64</RuntimeIdentifiers> to the csproj file
  4. Build and run the app in Release mode on x86_64 emulator crashes using dotnet build -c Release -t:Run

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 3
  • Comments: 25 (16 by maintainers)

Most upvoted comments

I was able to create some really minimal recreational steps, not even depending on any external libraries.

  1. Create new default Android App using dotnet new android
  2. Add <RuntimeIdentifiers>android-arm64</RuntimeIdentifiers> to csproj
  3. Run on default emulator [Pixel (+Store) x86_64 Android 13.0 with Google APIs] through Visual Studio 2022

This will reproducibly result in the app failing, even when targeting .NET MAUI 7:

Time	Device Name	Type	PID	Tag	Message
07-21 07:36:31.534	android_emulator_33	Error	8151	com.companyname.AndroidApp4	* Assertion at /__w/1/s/src/mono/mono/utils/mono-context.c:539, condition `fpctx->head.magic == FPSIMD_MAGIC' not met

I tested it against the x86_64 emulators for API 30, 31 and 33 and all are crashing.

If I try it with dotnet build -c Debug -r android-arm64 -t:Run --self-contained like you did, it seems to work. So it seems it might be related to the debugger.

  • Build & debug this app on an x86_64 API 30 emulator: App34.zip

I think as long as you’re using VS 2022, the issue should repro.

To workaround, you can either go to Project properties | Android Options | Advanced, and enable all ABIs:

image

Or Release builds also happen to work, not sure why.

The fix to this issue has been backported to .NET7 servicing and will be available soon.

and therefore only end up in APKs targeting net7.0-android or .NET 8 Preview without option to bring it in through NuGet packages, right?

That’s correct.

Setting AndroidSupportedAbis is not supported anymore as workaround starting with .NET 6. It will be force-overwritten here:

https://github.com/xamarin/xamarin-android/blob/main/src/Xamarin.Android.Build.Tasks/Tasks/RuntimeIdentifierToAbi.cs#L29-L34

Setting <RuntimeIdentifiers>android-arm64;android-x64</RuntimeIdentifiers> fails at runtime, since native libs are missing (grpc_csharp_ext in my case, which is why I would need to use android-arm64 only but with x86_64 being allowed as emulator).

Using Release mode but without success. We used android-x86 in the past, which is not supported on Android 12+ anymore.