sentry-dotnet icon indicating copy to clipboard operation
sentry-dotnet copied to clipboard

Sentry.Maui doesn't work when deploying for iOS using "Hot Restart"

Open legrignotin opened this issue 2 years ago • 14 comments

Package

Sentry.Maui

.NET Flavor

Other

.NET Version

6.0.304

OS

iOS

SDK Version

3.21.0-preview.3

Self-Hosted Sentry Version

No response

Steps to Reproduce

  • Create a MAUI Application
  • Add Sentry NuGet
  • Add Following code:
         builder.UseSentry(options =>
         {
             // The DSN is the only required setting.
             options.Dsn = "MY DSN";


             // Use debug mode if you want to see what the SDK is doing.
             // Debug messages are written to stdout with Console.Writeline,
             // and are viewable in your IDE's debug console or with 'adb logcat', etc.
             // This option is not recommended when deploying your application.
#if DEBUG
             options.Debug = true;
#endif

             // Set TracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
             // We recommend adjusting this value in production.
             options.TracesSampleRate = 1.0;
             options.AttachStacktrace = true;
#if ANDROID
             options.Android.AttachScreenshot = true;
#endif
             options.CacheDirectoryPath = FileSystem.Current.AppDataDirectory;
         });
  • Build & Launch with Hot Restart on a Iphone (Iphone SE 2020)

Expected Result

The application launch without any error or crash

Actual Result

The application crash.

[0:] An error occurred: 'Could not create an native instance of the type 'SentryCocoa.SentryOptions': the native class hasn't been loaded. It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false.'. Callstack: ' at Foundation.NSObject.InitializeObject(Boolean alloced) at Foundation.NSObject..ctor(NSObjectFlag x) at SentryCocoa.SentryOptions..ctor() in //src/Sentry/obj/Release/net6.0-ios/iOS/SentryCocoa/SentryOptions.g.cs:line 59 at Sentry.SentrySdk.InitSentryCocoaSdk(SentryOptions options) in //src/Sentry/Platforms/iOS/SentrySdk.cs:line 22 at Sentry.SentrySdk.InitHub(SentryOptions options) in //src/Sentry/SentrySdk.cs:line 60 at Sentry.SentrySdk.Init(SentryOptions options) in //src/Sentry/SentrySdk.cs:line 109 at Sentry.Maui.Internal.SentryMauiInitializer.Initialize(IServiceProvider services) in /_/src/Sentry.Maui/Internal/SentryMauiInitializer.cs:line 12 at Microsoft.Maui.Hosting.MauiAppBuilder.Build() at Mobile.MauiProgram.CreateMauiApp() in C:\Users\m\source\repos\Mobile\MauiProgram.cs:line 35 at Mobile.AppDelegate.CreateMauiApp() in C:\Users\m\source\repos\Mobile\Platforms\iOS\AppDelegate.cs:line 8 at Microsoft.Maui.MauiUIApplicationDelegate.WillFinishLaunching(UIApplication application, NSDictionary launchOptions) at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) at Mobile.Program.Main(String[] args) in C:\Users\m\source\repos\Mobile\Platforms\iOS\Program.cs:line 13 at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)'

legrignotin avatar Oct 04 '22 14:10 legrignotin

Thanks for reporting. I'll investigate.

mattjohnsonpint avatar Oct 04 '22 16:10 mattjohnsonpint

Hi, a few questions:

  • Is this a physical device, or a simulator?
  • What version of iOS is it using?
  • Does it only happen with hot reload? Or does it happen without it?

Also, please verify your .NET version (6.0.540 isn't out yet). Paste the result of dotnet --info here please.

Thanks

mattjohnsonpint avatar Oct 04 '22 21:10 mattjohnsonpint

Hi, thanks :)

  • It's a physical device : Iphone SE 2020 (MX9U2ZD/A)
  • It's on IOS 15.7
  • Having no MAC around ATM I can't tell :/ Everything is working fine on Android though (emulator and physical devices)

Oops sorry i've double checked and edited the post => it's 6.0.304

legrignotin avatar Oct 04 '22 23:10 legrignotin

I assume you are deploying with VS for Mac 2022 Preview using a local provisoning profile then? Or some other way?

mattjohnsonpint avatar Oct 05 '22 00:10 mattjohnsonpint

I wonder if somehow our native sdk didn't get linked in the app.

bruno-garcia avatar Oct 05 '22 00:10 bruno-garcia

I'm actually using Visual Studio Entreprise 2022 (Windows) - Version 17.4.0 Preview 2.1 I am using a development provisioning profile: image

legrignotin avatar Oct 05 '22 09:10 legrignotin

I wonder if somehow our native sdk didn't get linked in the app.

If that was the case, I should be able to reproduce it easily. So far, I haven't been able to, either on simulators or on a physical device, though my devices are a bit older.

I've ordered a iPhone SE 2020 for testing. I'll get back to you after I've tried on that model.

mattjohnsonpint avatar Oct 05 '22 14:10 mattjohnsonpint

I'm actually using Visual Studio Entreprise 2022 (Windows) - Version 17.4.0 Preview 2.1

With Pair to Mac I assume?

I'll try that way and see if there's any difference. I usually deploy directly from a Mac when testing.

mattjohnsonpint avatar Oct 05 '22 14:10 mattjohnsonpint

Nope! Actually with Hot Restart there's no need to Pair to Mac :)

Thanks for investigating!

legrignotin avatar Oct 05 '22 14:10 legrignotin

Wow, ok. I didn't know about this.

TIL that Hot Restart and Hot Reload are not the same things. Microsoft and naming things... lol 😅

mattjohnsonpint avatar Oct 05 '22 23:10 mattjohnsonpint

And here's the culprit:

https://learn.microsoft.com/en-us/dotnet/maui/deployment/hot-restart#prevent-code-from-executing

... Similarly, static iOS libraries and frameworks aren't supported and you may see runtime errors or crashes if your app attempts to load these.

It looks like I'll have to put some #if !HOTRESTART blocks around where we initialize the Sentry Cocoa SDK.

Of course this also means that the features of Sentry.Maui that depend on the Cocoa SDK won't operate. For example, capturing native crashes, jailbroken device detection, etc.

(Update: Our library is not static, so actually the statement in the docs is not applicable here. See further down for more details.)

mattjohnsonpint avatar Oct 05 '22 23:10 mattjohnsonpint

In the short term, if you don't need Sentry while developing locally, you could do that at initialization time. For example:

public static MauiApp CreateMauiApp() =>
    MauiApp.CreateBuilder()
        .UseMauiApp<App>()

#if !HOTRESTART
        .UseSentry(options =>
        {
            options.Dsn = // your dsn, etc.
        })
#endif

        // The remainder of your configuration
        .Build();
}

mattjohnsonpint avatar Oct 05 '22 23:10 mattjohnsonpint

Perfect! Thanks :)

legrignotin avatar Oct 10 '22 12:10 legrignotin

Apparently the issue is more complicated than I first understood. It is also affecting MAUI packages from others, including DevExpress. See https://github.com/dotnet/maui/issues/10800

We both have bindings to iOS projects via XCFramework packages, which apparently are not currently supported by Hot Restart. They contain dynamic libraries, not static libraries - so they should work, but currently they do not. The issue needs to be fixed in Hot Restart itself, by the Visual Studio team. If you could please upvote and add feedback to this issue that would help.

In the meantime, I will test this out myself and also see if I can find any workaround. I can't make any promises though.

Thanks for your patience.

mattjohnsonpint avatar Oct 28 '22 20:10 mattjohnsonpint

I've created a workaround. See https://github.com/dotnet/maui/issues/10800#issuecomment-1301564278

I haven't decided yet if I want to worm this into Sentry's nugets yet or not. In the meantime, you can add the workaround to your own csproj.

mattjohnsonpint avatar Nov 03 '22 02:11 mattjohnsonpint

Based on https://github.com/xamarin/xamarin-macios/issues/16571#issuecomment-1306715518, I've decided we should incorporate the workaround in the Sentry.Maui nuget. That will also make it easier to fix any subsequent issues that may arise.

mattjohnsonpint avatar Nov 09 '22 20:11 mattjohnsonpint

Sorry Matt, it's still not working for me. Crashes with the same trace as before. Sample code app at https://drive.google.com/file/d/1TmkncEencVyvU_dmdX1EDFGYJClCM1yb/view?usp=share_link . Tx

plattski avatar Nov 11 '22 14:11 plattski

Thanks, I will continue to investigate.

mattjohnsonpint avatar Nov 14 '22 19:11 mattjohnsonpint

@plattski - I tried your sample app, and it worked for me. Would you please capture a binlog so I can debug further? The best way I've found that captures the hotrestart build is to install the VS Project System Tools 2022 extensions. Then go to View > Other Windows > Build Logging, and click the green "start logging builds" button. Then build and run on your device using hot restart, and it will capture logs from several targets. I only need the one from the build target. Save that, zip it, and paste it here (you can paste zips directly into github issues).

Assuming that it fails as before, the binlog will show the path that should be invoked with the custom target.

Thanks.

mattjohnsonpint avatar Nov 14 '22 20:11 mattjohnsonpint

Thanks so much for checking. I’ll do that first thing tomorrow.

plattski avatar Nov 14 '22 21:11 plattski

Doing some more testing, I think I may have found the problem. Try changing the last line of the workaround:

from

<_HotRestartFrameworks Include="@(_HotRestartFrameworksFromPackages)" />

to:

<_HotRestartFrameworks Include="@(_HotRestartFrameworksFromPackages -> TrimEnd('\'))" />

Please let me know if it works after that. Thanks.

mattjohnsonpint avatar Nov 14 '22 22:11 mattjohnsonpint

I added the workaround in #2047, with a few modifications to keep us from stepping on the full fix when merged by Microsoft. I tested locally by creating a set of private nuget packages and using them in a new MAUI project on Windows. It built and deployed with Hot Restart without failure.

@plattski @legrignotin (and others) - If you want to try yourself before we release, grab this zip:

Sentry.3.23.2-private.zip

Extract that zip to a folder somewhere, then add a nuget.config to your solution dir and add a path to that folder, such as:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="local" value="C:\path\to\the\private\packages" />
    <add key="nuget" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
</configuration>

Then bump the package reference in the project to match:

<PackageReference Include="Sentry.Maui" Version="3.23.2-private-preview.3" />

Remove any previous workaround code from the csproj, as it's now delivered as a transitive build dependency in the Sentry.Bindings.Cocoa package. (Remove any #if !HOTRESTART when adding Sentry as well.)

It should work now via Visual Studio deploy to device with hot restart.

Assuming this works for everyone else as it did for me, the fix will be in the next release - so just use the private build only to validate this. Thanks.

mattjohnsonpint avatar Nov 14 '22 23:11 mattjohnsonpint

This one worked for me, in the bare-bones sample that I posted, and in two other, more functional apps. I think you've got it, at least for me, at least for now. Tx

plattski avatar Nov 15 '22 21:11 plattski

This is resolved in the latest 3.24.0 release. Thanks all!

mattjohnsonpint avatar Nov 18 '22 05:11 mattjohnsonpint