From 5bb3b59ce25c2e0a61ddf33bdba884195ce0adfd Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Jan 2026 10:25:37 +0100 Subject: [PATCH 01/12] Moved native functionality from 'Unity' to 'Unity.Native' --- .../NativeContextWriter.cs | 2 +- .../Sentry.Unity.Android.csproj | 1 + .../CFunctions.cs | 68 +++++++++++-------- .../ContextWriterUtils.cs} | 4 +- .../NativeContextWriter.cs | 12 ++-- .../NativeDebugImageProvider.cs | 9 +++ .../NativeScopeObserver.cs | 1 - .../Properties/AssemblyInfo.cs | 1 + src/Sentry.Unity.Native/SentryNative.cs | 2 +- src/Sentry.Unity/INativeDebugImageProvider.cs | 15 ++++ src/Sentry.Unity/Il2CppEventProcessor.cs | 4 +- src/Sentry.Unity/SentryUnityOptions.cs | 5 ++ 12 files changed, 83 insertions(+), 41 deletions(-) rename src/{Sentry.Unity/NativeUtils => Sentry.Unity.Native}/CFunctions.cs (86%) rename src/{Sentry.Unity/NativeUtils/ContextWriter.cs => Sentry.Unity.Native/ContextWriterUtils.cs} (98%) create mode 100644 src/Sentry.Unity.Native/NativeDebugImageProvider.cs create mode 100644 src/Sentry.Unity/INativeDebugImageProvider.cs diff --git a/src/Sentry.Unity.Android/NativeContextWriter.cs b/src/Sentry.Unity.Android/NativeContextWriter.cs index 573a8f2e6..7a4162145 100644 --- a/src/Sentry.Unity.Android/NativeContextWriter.cs +++ b/src/Sentry.Unity.Android/NativeContextWriter.cs @@ -1,4 +1,4 @@ -using CWUtil = Sentry.Unity.NativeUtils.ContextWriter; +using CWUtil = Sentry.Unity.Native.ContextWriterUtils; namespace Sentry.Unity.Android; diff --git a/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj b/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj index e84334f9f..f229e3325 100644 --- a/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj +++ b/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj @@ -6,6 +6,7 @@ + diff --git a/src/Sentry.Unity/NativeUtils/CFunctions.cs b/src/Sentry.Unity.Native/CFunctions.cs similarity index 86% rename from src/Sentry.Unity/NativeUtils/CFunctions.cs rename to src/Sentry.Unity.Native/CFunctions.cs index 76088e02b..a3d0a2e4f 100644 --- a/src/Sentry.Unity/NativeUtils/CFunctions.cs +++ b/src/Sentry.Unity.Native/CFunctions.cs @@ -4,10 +4,16 @@ using Sentry.Protocol; using UnityEngine; -namespace Sentry.Unity.NativeUtils; +namespace Sentry.Unity.Native; internal static class C { +#if SENTRY_NATIVE_PLAYSTATION || SENTRY_NATIVE_SWITCH + private const string SentryLib = "__Internal"; +#else + private const string SentryLib = "sentry"; +#endif + internal static void SetValueIfNotNull(sentry_value_t obj, string key, string? value) { if (value is not null) @@ -40,6 +46,14 @@ internal static void SetValueIfNotNull(sentry_value_t obj, string key, double? v } } + internal static void SetValueIfNotNull(sentry_value_t obj, string key, long? value) + { + if (value.HasValue) + { + _ = sentry_value_set_by_key(obj, key, sentry_value_new_double(value.Value)); + } + } + internal static sentry_value_t? GetValueOrNul(sentry_value_t obj, string key) { var cValue = sentry_value_get_by_key(obj, key); @@ -77,78 +91,78 @@ internal static void SetValueIfNotNull(sentry_value_t obj, string key, double? v return null; } - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_object(); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_null(); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_bool(int value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_double(double value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_int32(int value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_string(string value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_new_breadcrumb(string? type, string? message); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern int sentry_value_set_by_key(sentry_value_t value, string k, sentry_value_t v); internal static bool IsNull(sentry_value_t value) => sentry_value_is_null(value) != 0; - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern int sentry_value_is_null(sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern int sentry_value_as_int32(sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern double sentry_value_as_double(sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern IntPtr sentry_value_as_string(sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern UIntPtr sentry_value_get_length(sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_get_by_index(sentry_value_t value, UIntPtr index); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern sentry_value_t sentry_value_get_by_key(sentry_value_t value, string key); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_set_context(string key, sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_add_breadcrumb(sentry_value_t breadcrumb); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_set_tag(string key, string value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_remove_tag(string key); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_set_user(sentry_value_t user); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_remove_user(); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_set_extra(string key, sentry_value_t value); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_remove_extra(string key); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_set_trace(string traceId, string parentSpanId); internal static readonly Lazy> DebugImages = new(LoadDebugImages); @@ -202,10 +216,10 @@ private static IEnumerable LoadDebugImages() // Returns a new reference to an immutable, frozen list. // The reference must be released with `sentry_value_decref`. - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern sentry_value_t sentry_get_modules_list(); - [DllImport("sentry")] + [DllImport(SentryLib)] internal static extern void sentry_value_decref(sentry_value_t value); // native union sentry_value_u/t diff --git a/src/Sentry.Unity/NativeUtils/ContextWriter.cs b/src/Sentry.Unity.Native/ContextWriterUtils.cs similarity index 98% rename from src/Sentry.Unity/NativeUtils/ContextWriter.cs rename to src/Sentry.Unity.Native/ContextWriterUtils.cs index ec8fe9473..c825c3ad5 100644 --- a/src/Sentry.Unity/NativeUtils/ContextWriter.cs +++ b/src/Sentry.Unity.Native/ContextWriterUtils.cs @@ -1,6 +1,6 @@ -namespace Sentry.Unity.NativeUtils; +namespace Sentry.Unity.Native; -internal static class ContextWriter +internal static class ContextWriterUtils { internal static void WriteApp(string? AppStartTime, string? AppBuildType) { diff --git a/src/Sentry.Unity.Native/NativeContextWriter.cs b/src/Sentry.Unity.Native/NativeContextWriter.cs index 1c686abb1..fce658bc1 100644 --- a/src/Sentry.Unity.Native/NativeContextWriter.cs +++ b/src/Sentry.Unity.Native/NativeContextWriter.cs @@ -1,5 +1,3 @@ -using CWUtil = Sentry.Unity.NativeUtils.ContextWriter; - namespace Sentry.Unity.Native; internal class NativeContextWriter : ContextWriter @@ -40,11 +38,11 @@ protected override void WriteScope( string? UnityRenderingThreadingMode ) { - CWUtil.WriteApp(AppStartTime, AppBuildType); + ContextWriterUtils.WriteApp(AppStartTime, AppBuildType); - CWUtil.WriteOS(OperatingSystemRawDescription); + ContextWriterUtils.WriteOS(OperatingSystemRawDescription); - CWUtil.WriteDevice( + ContextWriterUtils.WriteDevice( DeviceProcessorCount, DeviceCpuDescription, DeviceTimezone, @@ -57,7 +55,7 @@ protected override void WriteScope( DeviceMemorySize ); - CWUtil.WriteGpu( + ContextWriterUtils.WriteGpu( GpuId, GpuName, GpuVendorName, @@ -74,7 +72,7 @@ protected override void WriteScope( GpuMultiThreadedRendering, GpuGraphicsShaderLevel); - CWUtil.WriteUnity( + ContextWriterUtils.WriteUnity( EditorVersion, UnityInstallMode, UnityTargetFrameRate, diff --git a/src/Sentry.Unity.Native/NativeDebugImageProvider.cs b/src/Sentry.Unity.Native/NativeDebugImageProvider.cs new file mode 100644 index 000000000..3c813959e --- /dev/null +++ b/src/Sentry.Unity.Native/NativeDebugImageProvider.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using Sentry.Protocol; + +namespace Sentry.Unity.Native; + +internal class NativeDebugImageProvider : INativeDebugImageProvider +{ + public IEnumerable GetDebugImages() => C.DebugImages.Value; +} diff --git a/src/Sentry.Unity.Native/NativeScopeObserver.cs b/src/Sentry.Unity.Native/NativeScopeObserver.cs index a5201125f..bebeae55c 100644 --- a/src/Sentry.Unity.Native/NativeScopeObserver.cs +++ b/src/Sentry.Unity.Native/NativeScopeObserver.cs @@ -1,5 +1,4 @@ using System; -using C = Sentry.Unity.NativeUtils.C; namespace Sentry.Unity.Native; diff --git a/src/Sentry.Unity.Native/Properties/AssemblyInfo.cs b/src/Sentry.Unity.Native/Properties/AssemblyInfo.cs index cbcda1aff..be1f926c8 100644 --- a/src/Sentry.Unity.Native/Properties/AssemblyInfo.cs +++ b/src/Sentry.Unity.Native/Properties/AssemblyInfo.cs @@ -1,3 +1,4 @@ using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Sentry.Unity.Android")] [assembly: InternalsVisibleTo("Sentry.Unity.Native.Tests")] diff --git a/src/Sentry.Unity.Native/SentryNative.cs b/src/Sentry.Unity.Native/SentryNative.cs index fb4c5aa59..455ab39cc 100644 --- a/src/Sentry.Unity.Native/SentryNative.cs +++ b/src/Sentry.Unity.Native/SentryNative.cs @@ -2,7 +2,6 @@ using Sentry.Extensibility; using Sentry.Unity.Integrations; using System.Collections.Generic; -using Sentry.Unity.NativeUtils; using UnityEngine; using UnityEngine.Analytics; @@ -60,6 +59,7 @@ internal static void Configure(SentryUnityOptions options, RuntimePlatform platf options.ScopeObserver = new NativeScopeObserver(options); options.EnableScopeSync = true; options.NativeContextWriter = new NativeContextWriter(); + options.NativeDebugImageProvider = new NativeDebugImageProvider(); options.DefaultUserId = GetInstallationId(); if (options.DefaultUserId is not null) diff --git a/src/Sentry.Unity/INativeDebugImageProvider.cs b/src/Sentry.Unity/INativeDebugImageProvider.cs new file mode 100644 index 000000000..244251582 --- /dev/null +++ b/src/Sentry.Unity/INativeDebugImageProvider.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Sentry.Protocol; + +namespace Sentry.Unity; + +/// +/// Provides debug images from the native SDK. +/// +public interface INativeDebugImageProvider +{ + /// + /// Gets the list of debug images from the native SDK. + /// + IEnumerable GetDebugImages(); +} diff --git a/src/Sentry.Unity/Il2CppEventProcessor.cs b/src/Sentry.Unity/Il2CppEventProcessor.cs index 279b0b846..44a09025b 100644 --- a/src/Sentry.Unity/Il2CppEventProcessor.cs +++ b/src/Sentry.Unity/Il2CppEventProcessor.cs @@ -5,7 +5,6 @@ using Sentry.Extensibility; using Sentry.Protocol; using Sentry.Unity.Integrations; -using Sentry.Unity.NativeUtils; using UnityEngine; using Application = UnityEngine.Application; @@ -231,7 +230,8 @@ public DebugImageInfo(DebugImage image) // Only on platforms where we actually use sentry-native. if (IsPlatformSupportedBySentryNative() && Options.IsNativeSupportEnabled()) { - var nativeDebugImages = C.DebugImages.Value; + var nativeDebugImages = Options.NativeDebugImageProvider?.GetDebugImages() + ?? Enumerable.Empty(); foreach (var image in nativeDebugImages) { if (image.ImageSize is null) diff --git a/src/Sentry.Unity/SentryUnityOptions.cs b/src/Sentry.Unity/SentryUnityOptions.cs index 155fd3716..2f41524b3 100644 --- a/src/Sentry.Unity/SentryUnityOptions.cs +++ b/src/Sentry.Unity/SentryUnityOptions.cs @@ -343,6 +343,11 @@ internal string? DefaultUserId /// internal ContextWriter? NativeContextWriter { get; set; } = null; + /// + /// Provides debug images from the native SDK for IL2CPP line number support. + /// + internal INativeDebugImageProvider? NativeDebugImageProvider { get; set; } = null; + /// /// Used to close down the native SDK /// From ac1e27cf6aac1cba0a33fd324e045e39c61b6bf9 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Jan 2026 17:29:42 +0100 Subject: [PATCH 02/12] Fixed artifact output --- package-dev/Runtime/Sentry.Unity.Android.dll.meta | 4 ++-- package-dev/Runtime/Sentry.Unity.Native.dll.meta | 4 ++-- src/Sentry.Unity.Android/Sentry.Unity.Android.csproj | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-dev/Runtime/Sentry.Unity.Android.dll.meta b/package-dev/Runtime/Sentry.Unity.Android.dll.meta index a5fde1b78..60106f4f9 100644 --- a/package-dev/Runtime/Sentry.Unity.Android.dll.meta +++ b/package-dev/Runtime/Sentry.Unity.Android.dll.meta @@ -17,7 +17,7 @@ PluginImporter: enabled: 0 settings: Exclude Android: 0 - Exclude Editor: 0 + Exclude Editor: 1 Exclude Linux64: 1 Exclude Lumin: 1 Exclude OSXUniversal: 1 @@ -40,7 +40,7 @@ PluginImporter: - first: Editor: Editor second: - enabled: 1 + enabled: 0 settings: CPU: AnyCPU DefaultValueInitialized: true diff --git a/package-dev/Runtime/Sentry.Unity.Native.dll.meta b/package-dev/Runtime/Sentry.Unity.Native.dll.meta index 6b6e91dde..0581715de 100644 --- a/package-dev/Runtime/Sentry.Unity.Native.dll.meta +++ b/package-dev/Runtime/Sentry.Unity.Native.dll.meta @@ -16,7 +16,7 @@ PluginImporter: second: enabled: 0 settings: - Exclude Android: 1 + Exclude Android: 0 Exclude Editor: 1 Exclude Linux64: 0 Exclude OSXUniversal: 1 @@ -31,7 +31,7 @@ PluginImporter: - first: Android: Android second: - enabled: 0 + enabled: 1 settings: CPU: ARMv7 - first: diff --git a/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj b/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj index f229e3325..a620dd65c 100644 --- a/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj +++ b/src/Sentry.Unity.Android/Sentry.Unity.Android.csproj @@ -6,7 +6,7 @@ - + From 9b078a543e2a1094f5053a3afa9dcd167ca1eec9 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Jan 2026 17:31:34 +0100 Subject: [PATCH 03/12] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 700aaf739..21766ee8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixes +- Fixed scope sync for PlayStation ([#2477](https://github.com/getsentry/sentry-unity/pull/2477)) - Automatically captured transactions and spans now have their `Origin` correctly set. ([#2464](https://github.com/getsentry/sentry-unity/pull/2464)) ### Dependencies From 90eef6b57b389a3df8a3271843edf8a52f14f486 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 15 Jan 2026 11:31:01 +0100 Subject: [PATCH 04/12] Updated the bridge as well --- src/Sentry.Unity.Native/SentryNativeBridge.cs | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/Sentry.Unity.Native/SentryNativeBridge.cs b/src/Sentry.Unity.Native/SentryNativeBridge.cs index b73ec7203..2bd1a831d 100644 --- a/src/Sentry.Unity.Native/SentryNativeBridge.cs +++ b/src/Sentry.Unity.Native/SentryNativeBridge.cs @@ -14,6 +14,12 @@ namespace Sentry.Unity.Native; /// internal static class SentryNativeBridge { +#if SENTRY_NATIVE_PLAYSTATION || SENTRY_NATIVE_SWITCH + private const string SentryLib = "__Internal"; +#else + private const string SentryLib = "sentry"; +#endif + public static bool Init(SentryUnityOptions options) { _useLibC = Application.platform @@ -120,40 +126,40 @@ internal static string GetCacheDirectory(SentryUnityOptions options) internal static void ReinstallBackend() => sentry_reinstall_backend(); // libsentry.so - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern IntPtr sentry_options_new(); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_dsn(IntPtr options, string dsn); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_release(IntPtr options, string release); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_debug(IntPtr options, int debug); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_environment(IntPtr options, string environment); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_sample_rate(IntPtr options, double rate); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_database_path(IntPtr options, string path); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_database_pathw(IntPtr options, [MarshalAs(UnmanagedType.LPWStr)] string path); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_auto_session_tracking(IntPtr options, int debug); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_attach_screenshot(IntPtr options, int attachScreenshot); [UnmanagedFunctionPointer(CallingConvention.Cdecl, SetLastError = true)] private delegate void sentry_logger_function_t(int level, IntPtr message, IntPtr argsAddress, IntPtr userData); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_options_set_logger(IntPtr options, sentry_logger_function_t logger, IntPtr userData); // The logger we should forward native messages to. This is referenced by nativeLog() which in turn for. @@ -302,18 +308,18 @@ private static void WithMarshalledStruct(T structure, Action action) action(ptr); }); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern int sentry_init(IntPtr options); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern int sentry_close(); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern int sentry_get_crashed_last_run(); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern int sentry_clear_crashed_last_run(); - [DllImport("sentry")] + [DllImport(SentryLib)] private static extern void sentry_reinstall_backend(); } From 8d3bf87f36e3433518f30b4c62041e58a214cca5 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 15 Jan 2026 13:44:17 +0100 Subject: [PATCH 05/12] Updated --- Agents.md | 6 ++++-- src/Sentry.Unity.Native/CFunctions.cs | 2 +- src/Sentry.Unity.Native/SentryNativeBridge.cs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Agents.md b/Agents.md index b81241096..a3d9f582a 100644 --- a/Agents.md +++ b/Agents.md @@ -11,11 +11,13 @@ The Sentry Unity SDK provides error monitoring, performance tracing, and crash r ### Quick Commands +**IMPORTANT**: Always run `dotnet build` from the repository root. Never build specific `.csproj` files directly. + ```bash # Download prebuilt native SDKs dotnet msbuild /t:DownloadNativeSDKs src/Sentry.Unity -# Build the Unity SDK +# Build the Unity SDK (always from root, never target specific .csproj files) dotnet build # Run all tests @@ -249,7 +251,7 @@ Scripts involved: | macOS | Objective-C | `__Internal` | `SentryCocoaBridgeProxy.cs`, `SentryNativeCocoa.cs` | | Windows | P/Invoke | `sentry` | `SentryNativeBridge.cs`, `CFunctions.cs` | | Linux | P/Invoke | `sentry` | `SentryNativeBridge.cs`, `CFunctions.cs` | -| PlayStation | Static | `__Internal` | `CFunctions.cs` | +| PlayStation | P/Invoke | `sentry` | `SentryNativeBridge.cs`, `CFunctions.cs` | ### Native SDK Submodules diff --git a/src/Sentry.Unity.Native/CFunctions.cs b/src/Sentry.Unity.Native/CFunctions.cs index a3d0a2e4f..4a644e70c 100644 --- a/src/Sentry.Unity.Native/CFunctions.cs +++ b/src/Sentry.Unity.Native/CFunctions.cs @@ -8,7 +8,7 @@ namespace Sentry.Unity.Native; internal static class C { -#if SENTRY_NATIVE_PLAYSTATION || SENTRY_NATIVE_SWITCH +#if SENTRY_NATIVE_SWITCH private const string SentryLib = "__Internal"; #else private const string SentryLib = "sentry"; diff --git a/src/Sentry.Unity.Native/SentryNativeBridge.cs b/src/Sentry.Unity.Native/SentryNativeBridge.cs index 2bd1a831d..5a999d291 100644 --- a/src/Sentry.Unity.Native/SentryNativeBridge.cs +++ b/src/Sentry.Unity.Native/SentryNativeBridge.cs @@ -14,7 +14,7 @@ namespace Sentry.Unity.Native; /// internal static class SentryNativeBridge { -#if SENTRY_NATIVE_PLAYSTATION || SENTRY_NATIVE_SWITCH +#if SENTRY_NATIVE_SWITCH private const string SentryLib = "__Internal"; #else private const string SentryLib = "sentry"; From e64b9104eefbc8943c184f43c2abaa8dc2fd9abe Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 15 Jan 2026 18:46:20 +0100 Subject: [PATCH 06/12] Updated the testing environment for local development --- Agents.md | 26 +++- Directory.Build.targets | 102 +-------------- scripts/report-test-results.ps1 | 88 +++++++++++++ scripts/run-tests.ps1 | 215 ++++++++++++++++++++++++++++++++ scripts/test-utils.ps1 | 62 +++++++++ 5 files changed, 387 insertions(+), 106 deletions(-) create mode 100644 scripts/report-test-results.ps1 create mode 100644 scripts/run-tests.ps1 create mode 100644 scripts/test-utils.ps1 diff --git a/Agents.md b/Agents.md index b81241096..8a2583310 100644 --- a/Agents.md +++ b/Agents.md @@ -18,12 +18,19 @@ dotnet msbuild /t:DownloadNativeSDKs src/Sentry.Unity # Build the Unity SDK dotnet build -# Run all tests -./test.sh +# Run all tests (builds SDK first) +pwsh scripts/run-tests.ps1 -# Run specific test targets -dotnet msbuild /t:UnityEditModeTest /p:Configuration=Release test/Sentry.Unity.Editor.Tests -dotnet msbuild /t:UnityPlayModeTest /p:Configuration=Release +# Run specific test types +pwsh scripts/run-tests.ps1 -PlayMode +pwsh scripts/run-tests.ps1 -EditMode + +# Run filtered tests +pwsh scripts/run-tests.ps1 -Filter "TestClassName" +pwsh scripts/run-tests.ps1 -PlayMode -Filter "Throttler" + +# Skip build for faster iteration +pwsh scripts/run-tests.ps1 -SkipBuild -Filter "MyTest" # Integration testing (local) ./test/Scripts.Integration.Test/integration-test.ps1 -Platform "macOS" -UnityVersion "2021.3.45f2" @@ -482,7 +489,14 @@ Key options: ### Running All Tests ```bash -./test.sh +# Run all tests (builds SDK first) +pwsh scripts/run-tests.ps1 + +# Run with filtering +pwsh scripts/run-tests.ps1 -Filter "TestClassName" + +# Skip build for faster iteration +pwsh scripts/run-tests.ps1 -SkipBuild ``` ### Integration Test Scripts diff --git a/Directory.Build.targets b/Directory.Build.targets index 5e471defd..ba5064f3f 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -398,7 +398,7 @@ Related: https://forum.unity.com/threads/6572-debugger-agent-unable-to-listen-on - + @@ -411,7 +411,7 @@ Related: https://forum.unity.com/threads/6572-debugger-agent-unable-to-listen-on - + @@ -465,104 +465,6 @@ File.WriteAllLines(PackageManifestFile, lines); - - - - - - - - - - - - - 1 ? "s" : "")}."; -Log.LogError(errorMessage); - -Success = false; - -void PrintFailedTests(XElement element) -{ - foreach (var descendant in element.Descendants()) - { - if (descendant.Name != "test-case" - || descendant.Attribute("result")?.Value != "Failed") - { - continue; - } - - if (descendant.Descendants().Any(d => d.Name == "test-case")) - { - PrintFailedTests(descendant); - } - else - { - var sb = new StringBuilder() - .Append("Test ") - .Append(descendant.Attribute("id")?.Value) - .Append(": ") - .AppendLine(descendant.Attribute("name")?.Value); - - var failure = descendant.Descendants("failure") - .Descendants("message") - .FirstOrDefault() - ?.Value; - - var stack = descendant.Descendants("failure") - .Descendants("stack-trace") - .FirstOrDefault() - ?.Value; - - sb.AppendLine(failure) - .Append("Test StackTrace: ") - .AppendLine(stack); - -// MSBuild is breaking each line as if it was an error per line and not a single error. -// So Log.LogError got replaced by Console.WriteLine for now. - Console.WriteLine(sb.ToString()); - } - } -} -]]> - - - - - - - - - - - - - - - - - - - - - - + diff --git a/scripts/download-native-sdks.ps1 b/scripts/download-native-sdks.ps1 new file mode 100644 index 000000000..63c3b9588 --- /dev/null +++ b/scripts/download-native-sdks.ps1 @@ -0,0 +1,136 @@ +#!/usr/bin/env pwsh + +param( + [Parameter()] + [string]$RepoRoot = "$PSScriptRoot/.." +) + +Set-StrictMode -Version latest +$ErrorActionPreference = 'Stop' +$PSNativeCommandUseErrorActionPreference = $true + +$ArtifactsDestination = Join-Path $RepoRoot "package-dev/Plugins" + +# SDK definitions with their existence checks +$SDKs = @( + @{ + Name = "Windows" + Destination = Join-Path $ArtifactsDestination "Windows" + CheckFile = "Sentry/sentry.dll" + }, + @{ + Name = "Linux" + Destination = Join-Path $ArtifactsDestination "Linux" + CheckFile = "Sentry/libsentry.so" + }, + @{ + Name = "Android" + Destination = Join-Path $ArtifactsDestination "Android" + CheckDir = "Sentry~" + ExpectedFileCount = 4 + } +) + +function Test-SDKPresent { + param($SDK) + + if ($SDK.ContainsKey('CheckFile')) { + $checkPath = Join-Path $SDK.Destination $SDK.CheckFile + return Test-Path $checkPath + } + elseif ($SDK.ContainsKey('CheckDir')) { + $checkPath = Join-Path $SDK.Destination $SDK.CheckDir + if (-not (Test-Path $checkPath)) { + return $false + } + $fileCount = (Get-ChildItem -Path $checkPath -File).Count + return $fileCount -ge $SDK.ExpectedFileCount + } + return $false +} + +function Get-LatestSuccessfulRunId { + Write-Host "Fetching latest successful CI run ID..." -ForegroundColor Yellow + + $result = gh run list --branch main --workflow CI --json "conclusion,databaseId" --jq 'first(.[] | select(.conclusion == "success") | .databaseId)' + + if (-not $result -or $result -eq "null") { + Write-Error "Failed to find a successful CI run on main branch" + exit 1 + } + + Write-Host "Found run ID: $result" -ForegroundColor Green + return $result +} + +function Download-SDK { + param( + [Parameter(Mandatory)] + [string]$Name, + [Parameter(Mandatory)] + [string]$Destination, + [Parameter(Mandatory)] + [string]$RunId + ) + + Write-Host "Downloading $Name SDK..." -ForegroundColor Yellow + + # Remove existing directory if present (partial download) + if (Test-Path $Destination) { + Write-Host " Removing existing directory..." -ForegroundColor Gray + Remove-Item -Path $Destination -Recurse -Force + } + + $artifactName = "$Name-sdk" + gh run download $RunId -n $artifactName -D $Destination + + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to download $Name SDK" + exit 1 + } + + Write-Host " Downloaded $Name SDK successfully" -ForegroundColor Green +} + +# Main logic +Write-Host "Checking native SDK status..." -ForegroundColor Cyan +Write-Host "" + +$sdksToDownload = @() + +foreach ($sdk in $SDKs) { + if (Test-SDKPresent $sdk) { + Write-Host "$($sdk.Name) SDK already present, skipping download." -ForegroundColor Green + } + else { + Write-Host "$($sdk.Name) SDK not found, will download." -ForegroundColor Yellow + $sdksToDownload += $sdk + } +} + +Write-Host "" + +if ($sdksToDownload.Count -eq 0) { + Write-Host "All native SDKs are already present." -ForegroundColor Green + exit 0 +} + +# Fetch run ID only if we need to download something +$runId = Get-LatestSuccessfulRunId + +foreach ($sdk in $sdksToDownload) { + Download-SDK -Name $sdk.Name -Destination $sdk.Destination -RunId $runId +} + +Write-Host "" +Write-Host "Restoring package-dev/Plugins to latest git commit..." -ForegroundColor Yellow +Push-Location $RepoRoot +try { + git restore package-dev/Plugins +} +finally { + Pop-Location +} + +Write-Host "" +Write-Host "Native SDK download completed successfully!" -ForegroundColor Green From e290f7ec80f3fa6b5ffaa035725bc6e4b4790689 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 16 Jan 2026 14:10:44 +0100 Subject: [PATCH 11/12] Added nativeimageprovider to android configuration --- src/Sentry.Unity.Android/SentryNativeAndroid.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Sentry.Unity.Android/SentryNativeAndroid.cs b/src/Sentry.Unity.Android/SentryNativeAndroid.cs index 0a04d476c..f93367a66 100644 --- a/src/Sentry.Unity.Android/SentryNativeAndroid.cs +++ b/src/Sentry.Unity.Android/SentryNativeAndroid.cs @@ -69,6 +69,7 @@ public static void Configure(SentryUnityOptions options) options.NativeContextWriter = new NativeContextWriter(SentryJava); options.ScopeObserver = new AndroidJavaScopeObserver(options, SentryJava); options.EnableScopeSync = true; + options.NativeDebugImageProvider = new Native.NativeDebugImageProvider(); options.CrashedLastRun = () => { options.DiagnosticLogger?.LogDebug("Checking for 'CrashedLastRun'"); From a8cf9c540376c4ff8b0ad0672e9045a3c34f1f34 Mon Sep 17 00:00:00 2001 From: Stefan Jandl Date: Fri, 16 Jan 2026 16:51:14 +0100 Subject: [PATCH 12/12] chore: Removed redundant clang invoking test (#2484) --- .../NativeOptionsTests.cs | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/test/Sentry.Unity.Editor.iOS.Tests/NativeOptionsTests.cs b/test/Sentry.Unity.Editor.iOS.Tests/NativeOptionsTests.cs index 814bd017b..71aecac29 100644 --- a/test/Sentry.Unity.Editor.iOS.Tests/NativeOptionsTests.cs +++ b/test/Sentry.Unity.Editor.iOS.Tests/NativeOptionsTests.cs @@ -1,54 +1,10 @@ -using System.Diagnostics; using System.IO; using NUnit.Framework; -using UnityEngine; namespace Sentry.Unity.Editor.iOS.Tests; public class NativeOptionsTests { - [Test] - public void GenerateOptions_NewSentryOptions_Compiles() - { - if (Application.platform != RuntimePlatform.OSXEditor) - { - Assert.Inconclusive("Skipping: Not on macOS"); - } - - const string testOptionsFileName = "testOptions.m"; - var nativeOptionsString = NativeOptions.Generate(new SentryUnityOptions()); - File.WriteAllText(testOptionsFileName, nativeOptionsString); - - var process = Process.Start("clang", $"-fsyntax-only {testOptionsFileName}"); - process.WaitForExit(); - - Assert.AreEqual(0, process.ExitCode); - - File.Delete(testOptionsFileName); - } - - [Test] - public void GenerateOptions_NewSentryOptionsGarbageAppended_FailsToCompile() - { - if (Application.platform != RuntimePlatform.OSXEditor) - { - Assert.Inconclusive("Skipping: Not on macOS"); - } - - const string testOptionsFileName = "testOptions.m"; - var nativeOptionsString = NativeOptions.Generate(new SentryUnityOptions()); - nativeOptionsString += "AppendedTextToFailCompilation"; - - File.WriteAllText(testOptionsFileName, nativeOptionsString); - - var process = Process.Start("clang", $"-fsyntax-only -framework Foundation {testOptionsFileName}"); - process.WaitForExit(); - - Assert.AreEqual(1, process.ExitCode); - - File.Delete(testOptionsFileName); - } - [Test] public void CreateOptionsFile_NewSentryOptions_FileCreated() {