diff --git a/.gitignore b/.gitignore index ea414b20d..ef01e63a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vs/ +.vsconfig *.user .idea/ obj/ diff --git a/CHANGELOG.md b/CHANGELOG.md index d4073371f..b2f8b3fbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,9 @@ ### Features - Android Native Support ([#307](https://github.com/getsentry/sentry-unity/pull/307)) -- iOS native bridge for scope sync ([#296](https://github.com/getsentry/sentry-unity/pull/296)) +- Android mark sessions as crashed ([#347](https://github.com/getsentry/sentry-unity/pull/347)) - Android native bridge for scope sync ([#308](https://github.com/getsentry/sentry-unity/pull/308)) +- iOS native bridge for scope sync ([#296](https://github.com/getsentry/sentry-unity/pull/296)) - Sample: Throw exceptions in C++ and Objective-C. C++ segfault ([#342](https://github.com/getsentry/sentry-unity/pull/342)) ### Fixes diff --git a/samples/unity-of-bugs/ProjectSettings/GraphicsSettings.asset b/samples/unity-of-bugs/ProjectSettings/GraphicsSettings.asset index 4654e1330..71c9e0f54 100644 --- a/samples/unity-of-bugs/ProjectSettings/GraphicsSettings.asset +++ b/samples/unity-of-bugs/ProjectSettings/GraphicsSettings.asset @@ -34,6 +34,7 @@ GraphicsSettings: - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16003, guid: 0000000000000000f000000000000000, type: 0} m_PreloadedShaders: [] m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} diff --git a/samples/unity-of-bugs/ProjectSettings/ProjectSettings.asset b/samples/unity-of-bugs/ProjectSettings/ProjectSettings.asset index 20b9b82c7..937024a58 100644 --- a/samples/unity-of-bugs/ProjectSettings/ProjectSettings.asset +++ b/samples/unity-of-bugs/ProjectSettings/ProjectSettings.asset @@ -49,7 +49,7 @@ PlayerSettings: m_StereoRenderingPath: 0 m_ActiveColorSpace: 0 m_MTRendering: 1 - m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + m_StackTraceTypes: 000000000000000000000000000000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 iosUseCustomAppBackgroundBehavior: 0 diff --git a/scripts/logcat.sh b/scripts/logcat.sh new file mode 100755 index 000000000..67ca1ea3f --- /dev/null +++ b/scripts/logcat.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e + +# 'Sentry' is the tag from the Android SDK. 'Unity' includes the C# layer in the Unity SDK: +adb logcat Unity:V Sentry:V '*:S' diff --git a/src/Sentry.Unity.Android/SentryJava.cs b/src/Sentry.Unity.Android/SentryJava.cs new file mode 100644 index 000000000..4a7b44c01 --- /dev/null +++ b/src/Sentry.Unity.Android/SentryJava.cs @@ -0,0 +1,32 @@ +using UnityEngine; + +namespace Sentry.Unity.Android +{ + /// + /// P/Invoke to `sentry-java` methods. + /// + /// + /// The `sentry-java` SDK on Android is brought in through the `sentry-android-core` + /// and `sentry-java` maven packages. + /// + /// + public static class SentryJava + { + /// + /// Returns whether or not the last run resulted in a crash. + /// + /// + /// This value is returned by the Android SDK and reports for both ART and NDK. + /// + /// + /// True if the last run terminated in a crash. No otherwise. + /// If the SDK wasn't able to find this information, null is returned. + /// + public static bool? CrashedLastRun() + { + using var jo = new AndroidJavaObject("io.sentry.Sentry"); + return jo.CallStatic("isCrashedLastRun") + ?.Call("booleanValue"); + } + } +} diff --git a/src/Sentry.Unity.Android/SentryNativeAndroid.cs b/src/Sentry.Unity.Android/SentryNativeAndroid.cs index 59def1c2a..6022f98ef 100644 --- a/src/Sentry.Unity.Android/SentryNativeAndroid.cs +++ b/src/Sentry.Unity.Android/SentryNativeAndroid.cs @@ -1,3 +1,5 @@ +using Sentry.Extensibility; + namespace Sentry.Unity.Android { /// @@ -15,6 +17,24 @@ public static void Configure(SentryUnityOptions options) { options.ScopeObserver = new AndroidJavaScopeObserver(options); options.EnableScopeSync = true; + options.CrashedLastRun = () => + { + var crashedLastRun = SentryJava.CrashedLastRun(); + if (crashedLastRun is null) + { + // Could happen if the Android SDK wasn't initialized before the .NET layer. + options.DiagnosticLogger? + .LogWarning("Unclear from the native SDK if the previous run was a crash. Assuming it was not."); + crashedLastRun = false; + } + else + { + options.DiagnosticLogger? + .LogDebug("Native Android SDK reported: 'crashedLastRun': '{0}'", crashedLastRun); + } + + return crashedLastRun.Value; + }; // At this point Unity has taken the signal handler and will not invoke the original handler (Sentry) // So we register our backend once more to make sure user-defined data is available in the crash report. SentryNative.ReinstallBackend(); diff --git a/src/Sentry.Unity/Integrations/UnityApplicationLoggingIntegration.cs b/src/Sentry.Unity/Integrations/UnityApplicationLoggingIntegration.cs index 41bd24e39..2d272f9aa 100644 --- a/src/Sentry.Unity/Integrations/UnityApplicationLoggingIntegration.cs +++ b/src/Sentry.Unity/Integrations/UnityApplicationLoggingIntegration.cs @@ -1,4 +1,5 @@ using System; +using Sentry.Extensibility; using Sentry.Integrations; using UnityEngine; @@ -75,12 +76,16 @@ internal void OnLogMessageReceived(string condition, string stackTrace, LogType private void OnQuitting() { + _sentryOptions?.DiagnosticLogger?.LogInfo("OnQuitting was invoked. Unhooking log callback and pausing session."); // Note: iOS applications are usually suspended and do not quit. You should tick "Exit on Suspend" in Player settings for iOS builds to cause the game to quit and not suspend, otherwise you may not see this call. // If "Exit on Suspend" is not ticked then you will see calls to OnApplicationPause instead. // Note: On Windows Store Apps and Windows Phone 8.1 there is no application quit event. Consider using OnApplicationFocus event when focusStatus equals false. // Note: On WebGL it is not possible to implement OnApplicationQuit due to nature of the browser tabs closing. _application.LogMessageReceived -= OnLogMessageReceived; - _hub?.EndSession(); + // 'OnQuitting' is invoked even when an uncaught exception happens in the ART. To make sure the .NET + // SDK checks with the native layer on restart if the previous run crashed (through the CrashedLastRun callback) + // we'll just pause sessions on shutdown. On restart they can be closed with the right timestamp and as 'exited'. + _hub?.PauseSession(); _hub?.FlushAsync(_sentryOptions?.ShutdownTimeout ?? TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); } diff --git a/src/sentry-dotnet b/src/sentry-dotnet index 8feefead6..388d2f35e 160000 --- a/src/sentry-dotnet +++ b/src/sentry-dotnet @@ -1 +1 @@ -Subproject commit 8feefead617b9c00c9a4cf2e0b1fa598aa83bf34 +Subproject commit 388d2f35e59aaaedc82c5ce3cfb174832776eaa9 diff --git a/src/sentry-java b/src/sentry-java index 1e831f8af..0496ac4b8 160000 --- a/src/sentry-java +++ b/src/sentry-java @@ -1 +1 @@ -Subproject commit 1e831f8afbba78a0f36559b93d7542807c734985 +Subproject commit 0496ac4b8ad1fde6347208b9fa27370cb45d58d9