Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Forms UWP app failing at run time with .net native tool chain but works otherwise

I have a Xamarin.Forms UWP app (Xamarin.Forms v3.4.0.1008975, UWP target/min version 16299, VS 2017 15.9.11). When compiled without the .net native tool chain it builds and runs correctly. When compiled with the .net native tool chain it builds fine but at run time it fails. This is an issue because I cannot release the app to the windows store. This app has previously (~10 months ago) been released to the store and worked correctly. There has been an extensive overhaul since then with updated versions of XF, Prism, sqlite packages and the addition of a couple of other packages amongst many other changes so it's nearly impossible to work out what change might have caused it.

I managed to get past some initial problems with the Rg.Plugins.Popup and Xam.Plugin.Iconize.FontAwesome packages by getting a list of assemblies for them and passing them into Xamarin.Forms.Forms.Init(e, assemblies); in App.xaml.cs in the UWP project. This fixed crashes/display issues with popups and font icons in my app.

When the app starts up I am seeing several handled FileNotFoundException on the Xamarin.Forms.Forms.Init(...) call of the form Cannot load assembly 'clrcompression'. No metadata found for this assembly.. The missing assemblies are:

  • clrcompression
  • e_sqlite3
  • libEGL
  • libGLESv2
  • libSkiaSharp
  • SkiaSharp.Views.Interop.UWP
  • sqlite3

As said these errors are handled and only seen when debugging. I've not seen any definite evidence that these errors are a problem as the app is definitely reading some data from Sqlite without error and I'm seeing images drawn correctly with SkiaSharp.

However I am getting other run time errors when I perform a certain actions that are crashing the app. For example Unhandled exception at 0x05F8F74C (SharedLibrary.dll) in MyApp.UWP.exe: 0x00001007. occurred. If I look in the threads window I get a bit more information:

Not Flagged >   13884   0   Worker Thread   <No Name>   
System.Private.SharedLibrary.Interop.Generated.dll!__Interop.api_ms_win_core_kernel32_legacy_l1_1_0_dll.PInvoke_RaiseFailFastException
System.Private.SharedLibrary.Interop.Generated.dll!__Interop.api_ms_win_core_kernel32_legacy_l1_1_0_dll.PInvoke_RaiseFailFastException(Interop._EXCEPTION_RECORD* pExceptionRecord, System.IntPtr pContextRecord, uint dwFlags)
System.Private.CoreLib.dll!Interop.mincore.PInvoke_RaiseFailFastException(Interop._EXCEPTION_RECORD* pExceptionRecord, System.IntPtr pContextRecord, uint dwFlags)
System.Private.CoreLib.dll!Interop.mincore.RaiseFailFastException(uint faultCode, System.IntPtr pExAddress, System.IntPtr pExContext) Line 122
System.Private.CoreLib.dll!System.RuntimeExceptionHelpers.FailFast(string message, System.Exception exception, System.RuntimeExceptionHelpers.RhFailFastReason reason, System.IntPtr pExAddress, System.IntPtr pExContext) Line 237
System.Private.CoreLib.dll!System.RuntimeExceptionHelpers.RuntimeFailFast(System.RuntimeExceptionHelpers.RhFailFastReason reason, System.Exception exception, System.IntPtr pExAddress, System.IntPtr pExContext) Line 200
[External Code]
System.Private.CoreLib.dll!Internal.Runtime.Augments.RuntimeAugments.RunFunctionWithConservativelyReportedBufferInternal<Internal.Runtime.TypeLoader.CallConversionParameters>(int cbBuffer, System.IntPtr pfnTargetToInvoke, ref Internal.Runtime.TypeLoader.CallConversionParameters context, ref System.Runtime.RuntimeImports.ConservativelyReportedRegionDesc regionDesc)
System.Private.CoreLib.dll!Internal.Runtime.Augments.RuntimeAugments.RunFunctionWithConservativelyReportedBuffer<Internal.Runtime.TypeLoader.CallConversionParameters>(int cbBuffer, System.IntPtr pfnTargetToInvoke, ref Internal.Runtime.TypeLoader.CallConversionParameters context)
System.Private.TypeLoader.dll!Internal.Runtime.TypeLoader.CallConverterThunk.CallConversionThunk(System.IntPtr callerTransitionBlockParam, System.IntPtr callConversionId)
[External Code]
Prism.dll!Prism.Mvvm.BindableBase.SetProperty<int?>(ref int? storage, int? value, string propertyName)
[External Code]
System.Private.CoreLib.dll!Internal.Runtime.Augments.RuntimeAugments.CallDescrWorker(System.IntPtr callDescr) Line 970
System.Private.TypeLoader.dll!Internal.Runtime.TypeLoader.CallConverterThunk.InvokeTarget(void* allocatedStackBuffer, ref Internal.Runtime.TypeLoader.CallConversionParameters conversionParams)
System.Private.CoreLib.dll!Internal.Runtime.Augments.RuntimeAugments.RunFunctionWithConservativelyReportedBufferInternal<Internal.Runtime.TypeLoader.CallConversionParameters>(int cbBuffer, System.IntPtr pfnTargetToInvoke, ref Internal.Runtime.TypeLoader.CallConversionParameters context, ref System.Runtime.RuntimeImports.ConservativelyReportedRegionDesc regionDesc)
System.Private.CoreLib.dll!Internal.Runtime.Augments.RuntimeAugments.RunFunctionWithConservativelyReportedBuffer<Internal.Runtime.TypeLoader.CallConversionParameters>(int cbBuffer, System.IntPtr pfnTargetToInvoke, ref Internal.Runtime.TypeLoader.CallConversionParameters context)
System.Private.TypeLoader.dll!Internal.Runtime.TypeLoader.CallConverterThunk.CallConversionThunk(System.IntPtr callerTransitionBlockParam, System.IntPtr callConversionId)
[External Code]
MyApp.dll!MyApp.ViewModels.AppLevel.AppStatusViewModel.CurrentSynchroniseJobTasksCount.set(int? value) Line 415
MyApp.dll!MyApp.ViewModels.AppLevel.AppStatusViewModel.HandleDataSyncStartEvent(string payload) Line 287
[External Code]
MyApp.dll!MyApp.Services.Synchronisation.DataSyncCoordinator.DoSynchronisationJob() Line 84
MyApp.dll!MyApp.Services.Synchronisation.DataSyncCoordinator.AttemptSynchronisationTask(MyApp.Services.Synchronisation.IDatabaseSyncJob job) Line 74
MyApp.dll!MyApp.Services.Synchronisation.DataSyncService.DeleteLocalData(string dbResetKey) Line 29
MyApp.dll!MyApp.ViewModels.ClearLocalDataPopupViewModel.Submit() Line 66
[Resuming Async Method]
[External Code]

Unfortunately while this tells me where the problem is happening it doesn't give me any clues as to why it's happening and how I might fix it. In this case it seems to be failing to set a property on a viewmodel but to even get to this point in the code it must have done this successfully in other places. I guess I'm really looking for guidance on how to investigate this/get more information as it's going to be hard to solve specific problems without some source code (which I cannot really provide). I have tried debugging with optimizations turned off which is often suggested but it's not provided any more information than I've posted here.

I'm also worried that even if I find out why this particular exception is happening and fix it that there might be many more issues in the app that only appear when .net native tool chain is used. Are there any tools I can use to help with this?

like image 387
rcarrington Avatar asked Nov 06 '22 18:11

rcarrington


1 Answers

So this turned out to be an issue with Prism (7.0.0.396) and the .net native. It looks like binding properties with a nullable type (int? in this case) using BindableBase.SetProperty fail when compiled with the .net native tool chain. The following appears to fix this:

public class BindableBaseWithFix : BindableBase
{
    protected virtual bool SetProperty<T>(ref T? storage, T? value, [CallerMemberName] string propertyName = null)
        where T : struct
    {
        if (EqualityComparer<T?>.Default.Equals(storage, value))
            return false;
        storage = value;
        RaisePropertyChanged(propertyName);
        return true;
    }
} 
like image 100
rcarrington Avatar answered Nov 14 '22 21:11

rcarrington