Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: android mark sessions as crashed #347

Merged
merged 5 commits into from
Sep 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.vs/
.vsconfig
*.user
.idea/
obj/
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions scripts/logcat.sh
Original file line number Diff line number Diff line change
@@ -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'
32 changes: 32 additions & 0 deletions src/Sentry.Unity.Android/SentryJava.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using UnityEngine;

namespace Sentry.Unity.Android
{
/// <summary>
/// P/Invoke to `sentry-java` methods.
/// </summary>
/// <remarks>
/// The `sentry-java` SDK on Android is brought in through the `sentry-android-core`
/// and `sentry-java` maven packages.
/// </remarks>
/// <see href="https://github.com/getsentry/sentry-java"/>
public static class SentryJava
{
/// <summary>
/// Returns whether or not the last run resulted in a crash.
/// </summary>
/// <remarks>
/// This value is returned by the Android SDK and reports for both ART and NDK.
/// </remarks>
/// <returns>
/// True if the last run terminated in a crash. No otherwise.
/// If the SDK wasn't able to find this information, null is returned.
/// </returns>
public static bool? CrashedLastRun()
{
using var jo = new AndroidJavaObject("io.sentry.Sentry");
return jo.CallStatic<AndroidJavaObject>("isCrashedLastRun")
?.Call<bool>("booleanValue");
}
}
}
20 changes: 20 additions & 0 deletions src/Sentry.Unity.Android/SentryNativeAndroid.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Sentry.Extensibility;

namespace Sentry.Unity.Android
{
/// <summary>
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Sentry.Extensibility;
using Sentry.Integrations;
using UnityEngine;

Expand Down Expand Up @@ -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();
}

Expand Down