From 5bb3b59ce25c2e0a61ddf33bdba884195ce0adfd Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Jan 2026 10:25:37 +0100 Subject: [PATCH 1/3] 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 2c592cbbaafbe3bf29ff3dfb62d99acc7fe03d43 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Jan 2026 11:28:02 +0100 Subject: [PATCH 2/3] Setting name at build time --- src/Sentry.Unity.Android/SentryJava.cs | 1 + .../Android/AndroidManifestConfiguration.cs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/Sentry.Unity.Android/SentryJava.cs b/src/Sentry.Unity.Android/SentryJava.cs index eb1e75310..bb888bf4a 100644 --- a/src/Sentry.Unity.Android/SentryJava.cs +++ b/src/Sentry.Unity.Android/SentryJava.cs @@ -132,6 +132,7 @@ public void Init(SentryUnityOptions options) androidOptions.Call("setSendDefaultPii", options.SendDefaultPii); androidOptions.Call("setEnableNdk", options.NdkIntegrationEnabled); androidOptions.Call("setEnableScopeSync", options.NdkScopeSyncEnabled); + androidOptions.Call("setNativeSdkName", "sentry.native.android.unity"); // Options that are not to be set by the user // We're disabling some integrations as to not duplicate event or because the SDK relies on the .NET SDK diff --git a/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs b/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs index 8c035ab67..a3a87de8c 100644 --- a/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs +++ b/src/Sentry.Unity.Editor/Android/AndroidManifestConfiguration.cs @@ -209,6 +209,7 @@ internal void ModifyManifest(string basePath) // Disabling the native in favor of the C# layer for now androidManifest.SetNdkEnabled(_options.NdkIntegrationEnabled); androidManifest.SetNdkScopeSync(_options.NdkScopeSyncEnabled); + androidManifest.SetNdkSdkName("sentry.native.android.unity"); androidManifest.SetAutoTraceIdGeneration(false); androidManifest.SetAutoSessionTracking(false); androidManifest.SetAutoAppLifecycleBreadcrumbs(false); @@ -493,6 +494,9 @@ internal void SetNdkEnabled(bool enableNdk) internal void SetNdkScopeSync(bool enableNdkScopeSync) => SetMetaData($"{SentryPrefix}.ndk.scope-sync.enable", enableNdkScopeSync.ToString()); + internal void SetNdkSdkName(string sdkName) + => SetMetaData($"{SentryPrefix}.ndk.sdk-name", sdkName); + internal void SetAutoTraceIdGeneration(bool enableAutoTraceIdGeneration) => SetMetaData($"{SentryPrefix}.traces.enable-auto-id-generation", enableAutoTraceIdGeneration.ToString()); From 06f39d957756ebf1366eb93dcc305b237db62f2f Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Jan 2026 11:31:04 +0100 Subject: [PATCH 3/3] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 700aaf739..99226bdd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixes +- When targeting Android, the capturing native SDK now has its name correctly set ([#2476](https://github.com/getsentry/sentry-unity/pull/2476)) - Automatically captured transactions and spans now have their `Origin` correctly set. ([#2464](https://github.com/getsentry/sentry-unity/pull/2464)) ### Dependencies