diff --git a/CHANGELOG.md b/CHANGELOG.md index 03ac7cede..81ebd2760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixes +- The SDK no longer sends events when it fails to initialize the native SDK on Windows and Linux and logs those instead. It also suppresses `EntryPointNotFoundException` if sentry-native is not available at runtime. Native crashes won't get capture but it'll continue to capture C# errors. ([#1898](https://github.com/getsentry/sentry-unity/pull/1898)) - The SDK no longer closes the underlying native SDK during the games shutdown if native support has not been enabled. This allows the SDK to support and capture errors in case of building the game as a library on a mobile (Android or iOS) game. ([#1897](https://github.com/getsentry/sentry-unity/pull/1897)) ### Dependencies diff --git a/package-dev/Runtime/SentryInitialization.cs b/package-dev/Runtime/SentryInitialization.cs index d164e8ae0..07669f266 100644 --- a/package-dev/Runtime/SentryInitialization.cs +++ b/package-dev/Runtime/SentryInitialization.cs @@ -60,7 +60,6 @@ public static void Init() if (options != null && options.ShouldInitializeSdk()) { SentryIntegrations.Configure(options); - Exception nativeInitException = null; try { @@ -76,20 +75,16 @@ public static void Init() } catch (DllNotFoundException e) { - nativeInitException = new Exception( + options.DiagnosticLogger?.LogError( "Sentry native-error capture configuration failed to load a native library. This usually " + "means the library is missing from the application bundle or the installation directory.", e); } catch (Exception e) { - nativeInitException = new Exception("Sentry native error capture configuration failed.", e); + options.DiagnosticLogger?.LogError("Sentry native error capture configuration failed.", e); } SentryUnity.Init(options); - if (nativeInitException != null) - { - SentrySdk.CaptureException(nativeInitException); - } #if !SENTRY_WEBGL if (options.TracesSampleRate > 0.0f && options.AutoStartupTraces) @@ -118,17 +113,6 @@ public static void Init() #endif } } - -#if SENTRY_NATIVE - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - public static void ReinstallBackend() - { - // At this point Unity has taken the signal handler and will not invoke our handler. So we register our - // backend once more to make sure user-defined data is available in the crash report and the SDK is able - // to capture the crash. - SentryNative.ReinstallBackend(); - } -#endif } public class SentryUnityInfo : ISentryUnityInfo diff --git a/src/Sentry.Unity.Native/SentryNative.cs b/src/Sentry.Unity.Native/SentryNative.cs index 3fec6e556..94d1227ab 100644 --- a/src/Sentry.Unity.Native/SentryNative.cs +++ b/src/Sentry.Unity.Native/SentryNative.cs @@ -2,6 +2,7 @@ using Sentry.Extensibility; using Sentry.Unity.Integrations; using System.Collections.Generic; +using UnityEngine; using UnityEngine.Analytics; namespace Sentry.Unity.Native; @@ -13,6 +14,9 @@ public static class SentryNative { private static readonly Dictionary PerDirectoryCrashInfo = new(); + private static bool ShouldReinstallBackend; + private static IDiagnosticLogger? Logger; + /// /// Configures the native SDK. /// @@ -20,11 +24,13 @@ public static class SentryNative /// Infos about the current Unity environment public static void Configure(SentryUnityOptions options, ISentryUnityInfo sentryUnityInfo) { - options.DiagnosticLogger?.LogInfo("Attempting to configure native support via the Native SDK"); + Logger = options.DiagnosticLogger; + + Logger?.LogInfo("Attempting to configure native support via the Native SDK"); if (!sentryUnityInfo.IsNativeSupportEnabled(options, ApplicationAdapter.Instance.Platform)) { - options.DiagnosticLogger?.LogDebug("Native support is disabled for '{0}'.", ApplicationAdapter.Instance.Platform); + Logger?.LogDebug("Native support is disabled for '{0}'.", ApplicationAdapter.Instance.Platform); return; } @@ -32,21 +38,21 @@ public static void Configure(SentryUnityOptions options, ISentryUnityInfo sentry { if (!SentryNativeBridge.Init(options, sentryUnityInfo)) { - options.DiagnosticLogger? + Logger? .LogWarning("Sentry native initialization failed - native crashes are not captured."); return; } } catch (Exception e) { - options.DiagnosticLogger? + Logger? .LogError(e, "Sentry native initialization failed - native crashes are not captured."); return; } ApplicationAdapter.Instance.Quitting += () => { - options.DiagnosticLogger?.LogDebug("Closing the sentry-native SDK"); + Logger?.LogDebug("Closing the sentry-native SDK"); SentryNativeBridge.Close(); }; options.ScopeObserver = new NativeScopeObserver(options); @@ -75,12 +81,41 @@ public static void Configure(SentryUnityOptions options, ISentryUnityInfo sentry crashedLastRun = SentryNativeBridge.HandleCrashedLastRun(options); PerDirectoryCrashInfo.Add(cacheDirectory, crashedLastRun); - options.DiagnosticLogger? + Logger? .LogDebug("Native SDK reported: 'crashedLastRun': '{0}'", crashedLastRun); } } options.CrashedLastRun = () => crashedLastRun; + + ShouldReinstallBackend = true; } - public static void ReinstallBackend() => SentryNativeBridge.ReinstallBackend(); + // We're calling this in `BeforeSceneLoad` instead of `SubsystemRegistration` as it's too soon and the + // SignalHandler would still get overwritten. + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void ReinstallBackend() + { + // The backend should only be reinstalled if the native SDK has been initialized successfully. + if (!ShouldReinstallBackend) + { + Logger?.LogWarning("Skipping reinstalling the native backend."); + return; + } + else + { + Logger?.LogDebug("Reinstalling the native backend to make sure we capture native crashes."); + } + + try + { + // At this point Unity has taken the signal handler and will not invoke our handler. So we register our + // backend once more to make sure user-defined data is available in the crash report and the SDK is able + // to capture the crash. + SentryNativeBridge.ReinstallBackend(); + } + catch (EntryPointNotFoundException e) + { + Logger?.LogError(e, "Native dependency not found. Did you delete sentry.dll or move files around?"); + } + } }