Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
275 changes: 238 additions & 37 deletions samples/unity-of-bugs/Assets/Scenes/3_AdditionalSamples.unity

Large diffs are not rendered by default.

27 changes: 26 additions & 1 deletion samples/unity-of-bugs/Assets/Scripts/AdditionalSampleButtons.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Threading;
#if UNITY_IOS
using System.Runtime.InteropServices;
#endif
using Sentry;
using Sentry.Unity;
using Unity.Burst;
Expand Down Expand Up @@ -48,10 +51,32 @@ public void CaptureMessageWithContext()
public void ApplicationNotResponding()
{
Debug.Log("Running Thread.Sleep() on the UI thread to trigger an ANR event.");
Thread.Sleep(6 * 1000); // ANR detection currently defaults to 5 seconds
Thread.Sleep(10 * 1000); // ANR detection currently defaults to 5 seconds
Debug.Log("Thread.Sleep() finished.");
}

public void ApplicationNotRespondingNative()
{
#if UNITY_ANDROID && !UNITY_EDITOR
Debug.Log("Stalling the main thread via Kotlin to trigger a native ANR event.");
using (var jo = new AndroidJavaObject("unity.of.bugs.KotlinPlugin"))
{
jo.CallStatic("applicationNotResponding");
}
#elif UNITY_IOS && !UNITY_EDITOR
Debug.Log("Stalling the main thread via Objective-C to trigger a native ANR event.");
applicationNotResponding();
#else
Debug.LogWarning("Native ANR sample requires running on Android or iOS.");
#endif
}

#if UNITY_IOS && !UNITY_EDITOR
// ObjectiveCPlugin.m
[DllImport("__Internal")]
private static extern void applicationNotResponding();
#endif

public void Assert() => UnityEngine.Assertions.Assert.IsTrue(false);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ object KotlinPlugin {
throw Exception("Kotlin 🐛 from a background thread.")
}
}
@JvmStatic fun applicationNotResponding() {
Log.i("test", "Stalling the main thread from Kotlin to trigger a native ANR.")
Thread.sleep(10 * 1000) // ANR detection currently defaults to 5 seconds
Log.i("test", "Kotlin main thread stall finished.")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,11 @@ void throwObjectiveC()
#endif
}

void applicationNotResponding()
{
NSLog(@"Stalling the main thread from Objective-C to trigger a native ANR.");
[NSThread sleepForTimeInterval:10.0]; // ANR detection currently defaults to 5 seconds
NSLog(@"Objective-C main thread stall finished.");
}

NS_ASSUME_NONNULL_END
2 changes: 1 addition & 1 deletion src/Sentry.Unity.Editor.iOS/NativeOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal static string Generate(SentryUnityOptions options)
@""maxBreadcrumbs"": @{options.MaxBreadcrumbs},
@""maxCacheItems"": @{options.MaxCacheItems},
@""enableAutoSessionTracking"": @NO,
@""enableAppHangTracking"": @NO,
@""enableAppHangTracking"": @{ToObjCString(options.IosNativeAnrEnabled)},
@""enableCaptureFailedRequests"": @{ToObjCString(options.CaptureFailedRequests)},
@""failedRequestStatusCodes"" : @[{failedRequestStatusCodesArray}],
@""sendDefaultPii"" : @{ToObjCString(options.SendDefaultPii)},
Expand Down
8 changes: 8 additions & 0 deletions src/Sentry.Unity.iOS/SentryCocoaBridgeProxy.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Runtime.InteropServices;
using Sentry.Extensibility;
using Sentry.Unity.Integrations;
using UnityEngine;

namespace Sentry.Unity.iOS;

Expand Down Expand Up @@ -66,6 +68,12 @@ public static bool Init(SentryUnityOptions options)
// See https://github.com/getsentry/sentry-unity/issues/1658
OptionsSetInt(cOptions, "enableNetworkBreadcrumbs", 0);

if (ApplicationAdapter.Instance.Platform == RuntimePlatform.IPhonePlayer)
{
Logger?.LogDebug("Setting EnableAppHangTracking: {0}", options.IosNativeAnrEnabled);
OptionsSetInt(cOptions, "enableAppHangTracking", options.IosNativeAnrEnabled ? 1 : 0);
}

Logger?.LogDebug("Setting EnableWatchdogTerminationTracking: {0}", options.IosWatchdogTerminationIntegrationEnabled);
OptionsSetInt(cOptions, "enableWatchdogTerminationTracking", options.IosWatchdogTerminationIntegrationEnabled ? 1 : 0);

Expand Down
6 changes: 6 additions & 0 deletions src/Sentry.Unity.iOS/SentryNativeCocoa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ internal static void Configure(SentryUnityOptions options, RuntimePlatform platf
}

options.ScopeObserver = new NativeScopeObserver("iOS", options);

if (options.IosNativeAnrEnabled)
{
Logger?.LogDebug("Disabling the C# ANR watchdog on iOS - sentry-cocoa handles app hang detection.");
options.DisableAnrIntegration();
}
Comment thread
bitsandfoxes marked this conversation as resolved.
Comment thread
bitsandfoxes marked this conversation as resolved.
}
else
{
Expand Down
12 changes: 12 additions & 0 deletions src/Sentry.Unity/SentryUnityOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@ public sealed class SentryUnityOptions : SentryOptions
/// </summary>
public bool IosWatchdogTerminationIntegrationEnabled { get; set; } = false;

/// <summary>
/// Enables ANR (app hang) detection on iOS through the native (sentry-cocoa) SDK.
/// When enabled, sentry-cocoa monitors the main thread for hangs and the Unity SDK's
/// C# ANR watchdog is skipped on iOS to avoid duplicate reports.
/// </summary>
/// <remarks>
/// sentry-cocoa observes the iOS run loop directly, which yields more accurate
/// app-hang detection than the Unity-side watchdog. Disable this only if you want
/// to fall back to the C# watchdog.
/// </remarks>
public bool IosNativeAnrEnabled { get; set; } = true;

/// <summary>
/// Whether the SDK should initialize the native SDK before the game starts. This bakes the options at build-time into
/// the generated Xcode project. Modifying the options at runtime will not affect the options used to initialize
Expand Down
26 changes: 26 additions & 0 deletions test/Sentry.Unity.Editor.iOS.Tests/NativeOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,32 @@ public void CreateOptionsFile_NewSentryOptions_ContainsSdkNameSetting()
File.Delete(testOptionsFileName);
}

[Test]
public void CreateOptionsFile_IosNativeAnrEnabled_SetsYes()
{
const string testOptionsFileName = "testOptions.m";

NativeOptions.CreateFile(testOptionsFileName, new SentryUnityOptions { IosNativeAnrEnabled = true });

var nativeOptions = File.ReadAllText(testOptionsFileName);
StringAssert.Contains("@\"enableAppHangTracking\": @YES", nativeOptions);

File.Delete(testOptionsFileName);
}

[Test]
public void CreateOptionsFile_IosNativeAnrDisabled_SetsNo()
{
const string testOptionsFileName = "testOptions.m";

NativeOptions.CreateFile(testOptionsFileName, new SentryUnityOptions { IosNativeAnrEnabled = false });

var nativeOptions = File.ReadAllText(testOptionsFileName);
StringAssert.Contains("@\"enableAppHangTracking\": @NO", nativeOptions);

File.Delete(testOptionsFileName);
}

[Test]
public void CreateOptionsFile_FilterBadGatewayEnabled_AddsFiltering()
{
Expand Down
Loading