Skip to content
Open
Show file tree
Hide file tree
Changes from 9 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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

### Features

- Added PlayStation Native Support. The SDK now automatically syncs the scope - tags, breadcrumbs, context - to the native layer, so native crashes have the same rich context as managed events. ([#2433](https://github.com/getsentry/sentry-unity/pull/2433))
- Added `SetBeforeSendScreenshot(Func<Texture2D, SentryEvent, Texture2D?>)` callback that provides the captured screenshot as a
`Texture2D` before JPEG compression. ([#2428](https://github.com/getsentry/sentry-unity/pull/2428))
This enables:
Expand All @@ -20,7 +21,7 @@
- Access to the event context for conditional processing
- Added `SetBeforeSendViewHierarchy(Func<ViewHierarchy, SentryEvent, ViewHierarchy?>)` callback that provides the captured
`ViewHierarchy` to be modified before compression. ([#2429](https://github.com/getsentry/sentry-unity/pull/2429))

### Dependencies

- Bump Cocoa SDK from v8.57.2 to v9.0.0-rc.0 ([#2424](https://github.com/getsentry/sentry-unity/pull/2424), [#2427](https://github.com/getsentry/sentry-unity/pull/2427))
Expand Down
4 changes: 3 additions & 1 deletion package-dev/Runtime/SentryInitialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#define SENTRY_NATIVE
#elif UNITY_GAMECORE
#define SENTRY_NATIVE
#elif UNITY_PS4 || UNITY_PS5
#define SENTRY_NATIVE
#elif UNITY_WEBGL
#define SENTRY_WEBGL
#endif
Expand Down Expand Up @@ -131,7 +133,7 @@ private Il2CppMethods _il2CppMethods
return null;
}

#if UNITY_ANDROID || UNITY_STANDALONE_LINUX
#if UNITY_ANDROID || UNITY_STANDALONE_LINUX || UNITY_PS4 || UNITY_PS5
// For ELF platforms, the 20-byte `NT_GNU_BUILD_ID` needs to be
// turned into a "little-endian GUID", which means the first three
// components need to be byte-swapped appropriately.
Expand Down
2 changes: 2 additions & 0 deletions package-dev/Runtime/io.sentry.unity.dev.runtime.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"LinuxStandalone64",
"Lumin",
"macOSStandalone",
"PS4",
"PS5",
"Stadia",
"Switch",
"WSA",
Expand Down
2 changes: 2 additions & 0 deletions package/Runtime/io.sentry.unity.runtime.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"LinuxStandalone64",
"Lumin",
"macOSStandalone",
"PS4",
"PS5",
"Stadia",
"Switch",
"WSA",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,12 @@ internal static void Display(ScriptableSentryUnityOptions options, SentryCliOpti
GUILayout.Label("Console", EditorStyles.boldLabel);

options.XboxNativeSupportEnabled = EditorGUILayout.Toggle(
new GUIContent("Xbox", "Whether to enable native crashes support on Xbox."),
new GUIContent("Xbox", "Whether to enable native crash support on Xbox."),
options.XboxNativeSupportEnabled);

options.PlayStationNativeSupportEnabled = EditorGUILayout.Toggle(
new GUIContent("PlayStation", "Whether to enable native crash support on PlayStation."),
options.PlayStationNativeSupportEnabled);
}

EditorGUI.indentLevel--;
Expand Down
21 changes: 19 additions & 2 deletions src/Sentry.Unity.Editor/Native/BuildPostProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Sentry.Extensibility;
using Sentry.Unity.Editor.ConfigurationWindow;
using System.Text.RegularExpressions;
using Microsoft.Extensions.FileSystemGlobbing;
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
Expand All @@ -18,7 +17,10 @@ public static class BuildPostProcess
public static void OnPostProcessBuild(BuildTarget target, string executablePath)
{
var targetGroup = BuildPipeline.GetBuildTargetGroup(target);
if (targetGroup is not BuildTargetGroup.Standalone and not BuildTargetGroup.GameCoreXboxSeries)
if (targetGroup is not BuildTargetGroup.Standalone
and not BuildTargetGroup.GameCoreXboxSeries
and not BuildTargetGroup.PS4
and not BuildTargetGroup.PS5)
{
return;
}
Expand Down Expand Up @@ -47,10 +49,12 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
// The executable path resolves to the following when pointing Unity into a `build/platform/` directory:
// - Desktop: `./samples/unity-of-bugs/builds/windows/unityofbugs.exe`
// - Xbox: `./samples/unity-of-bugs/builds/xsx/`
// - PlayStation: `./samples/unity-of-bugs/builds/ps5/`
var buildOutputDir = targetGroup switch
{
BuildTargetGroup.Standalone => Path.GetDirectoryName(executablePath),
BuildTargetGroup.GameCoreXboxSeries => executablePath,
BuildTargetGroup.PS4 or BuildTargetGroup.PS5 => executablePath,
_ => string.Empty
};

Expand Down Expand Up @@ -87,6 +91,7 @@ public static void OnPostProcessBuild(BuildTarget target, string executablePath)
BuildTarget.StandaloneOSX => options.MacosNativeSupportEnabled,
BuildTarget.StandaloneLinux64 => options.LinuxNativeSupportEnabled,
BuildTarget.GameCoreXboxSeries or BuildTarget.GameCoreXboxOne => options.XboxNativeSupportEnabled,
BuildTarget.PS4 or BuildTarget.PS5 => options.PlayStationNativeSupportEnabled,
_ => false,
};

Expand All @@ -108,6 +113,10 @@ private static void AddCrashHandler(IDiagnosticLogger logger, BuildTarget target
case BuildTarget.GameCoreXboxOne:
// No standalone crash handler for Xbox - comes with Breakpad
return;
case BuildTarget.PS4:
case BuildTarget.PS5:
// No standalone crash handler for PlayStation
return;
default:
throw new ArgumentException($"Unsupported build target: {target}");
}
Expand Down Expand Up @@ -158,6 +167,14 @@ private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget tar
paths += $" \"{xboxSentryPluginPath}\"";
}
break;
case BuildTarget.PS4:
case BuildTarget.PS5:
var playstationSentryPluginPath = Path.GetFullPath("Assets/Plugins/Sentry/");
if (Directory.Exists(playstationSentryPluginPath))
{
paths += $" \"{playstationSentryPluginPath}\"";
}
break;
case BuildTarget.StandaloneLinux64:
var linuxSentryDbg = Path.GetFullPath($"Packages/{SentryPackageInfo.GetName()}/Plugins/Linux/Sentry/libsentry.dbg.so");
if (File.Exists(linuxSentryDbg))
Expand Down
30 changes: 24 additions & 6 deletions src/Sentry.Unity.Native/SentryNativeBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ internal static class SentryNativeBridge
{
public static bool Init(SentryUnityOptions options)
{
_isLinux = Application.platform is RuntimePlatform.LinuxPlayer or RuntimePlatform.LinuxServer;
_useLibC = Application.platform
is RuntimePlatform.LinuxPlayer or RuntimePlatform.LinuxServer
or RuntimePlatform.PS4 or RuntimePlatform.PS5;

var cOptions = sentry_options_new();

Expand Down Expand Up @@ -139,7 +141,7 @@ internal static string GetCacheDirectory(SentryUnityOptions options)

// The logger we should forward native messages to. This is referenced by nativeLog() which in turn for.
private static IDiagnosticLogger? _logger;
private static bool _isLinux = false;
private static bool _useLibC = false;

// This method is called from the C library and forwards incoming messages to the currently set _logger.
[MonoPInvokeCallback(typeof(sentry_logger_function_t))]
Expand Down Expand Up @@ -183,20 +185,33 @@ private static void nativeLogImpl(int cLevel, IntPtr format, IntPtr args, IntPtr
try
{
// We cannot access C var-arg (va_list) in c# thus we pass it back to vsnprintf to do the formatting.
// For Linux, we must make a copy of the VaList to be able to pass it back...
if (_isLinux)
// For Linux and PlayStation, we must make a copy of the VaList to be able to pass it back...
if (_useLibC)
{
var argsStruct = Marshal.PtrToStructure<VaListLinux64>(args);
var formattedLength = 0;

// PlayStation uses a wrapper function to avoid IL2CPP conflicts with the Prospero SDK's vsnprintf
var isPlayStation = Application.platform is RuntimePlatform.PS4 or RuntimePlatform.PS5;

WithMarshalledStruct(argsStruct, argsPtr =>
{
formattedLength = 1 + vsnprintf_linux(IntPtr.Zero, UIntPtr.Zero, format, argsPtr);
formattedLength = 1 + (isPlayStation
? vsnprintf_ps(IntPtr.Zero, UIntPtr.Zero, format, argsPtr)
: vsnprintf_linux(IntPtr.Zero, UIntPtr.Zero, format, argsPtr));
});

WithAllocatedPtr(formattedLength, buffer =>
WithMarshalledStruct(argsStruct, argsPtr =>
{
vsnprintf_linux(buffer, (UIntPtr)formattedLength, format, argsPtr);
if (isPlayStation)
{
vsnprintf_ps(buffer, (UIntPtr)formattedLength, format, argsPtr);
}
else
{
vsnprintf_linux(buffer, (UIntPtr)formattedLength, format, argsPtr);
}
message = Marshal.PtrToStringAnsi(buffer);
}));
}
Expand Down Expand Up @@ -233,6 +248,9 @@ private static void nativeLogImpl(int cLevel, IntPtr format, IntPtr args, IntPtr
[DllImport("libc", EntryPoint = "vsnprintf")]
private static extern int vsnprintf_linux(IntPtr buffer, UIntPtr bufferSize, IntPtr format, IntPtr args);

[DllImport("sentry")]
private static extern int vsnprintf_ps(IntPtr buffer, UIntPtr bufferSize, IntPtr format, IntPtr args);

// https://stackoverflow.com/a/4958507/2386130
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct VaListLinux64
Expand Down
6 changes: 5 additions & 1 deletion src/Sentry.Unity/Il2CppEventProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,9 @@ or RuntimePlatform.LinuxServer
or RuntimePlatform.WindowsPlayer
or RuntimePlatform.WindowsServer
or RuntimePlatform.GameCoreXboxSeries
or RuntimePlatform.GameCoreXboxOne;
or RuntimePlatform.GameCoreXboxOne
or RuntimePlatform.PS4
or RuntimePlatform.PS5;
}

private string GetPlatformDebugImageType(RuntimePlatform? platform = null)
Expand All @@ -373,6 +375,8 @@ private string GetPlatformDebugImageType(RuntimePlatform? platform = null)
case RuntimePlatform.Android:
case RuntimePlatform.LinuxPlayer:
case RuntimePlatform.LinuxServer:
case RuntimePlatform.PS4:
case RuntimePlatform.PS5:
return "elf";
case RuntimePlatform.IPhonePlayer:
case RuntimePlatform.OSXPlayer:
Expand Down
6 changes: 6 additions & 0 deletions src/Sentry.Unity/Integrations/UnityScopeIntegration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ is RuntimePlatform.GameCoreXboxSeries
{
operatingSystemContext.Name = "Xbox";
}
else if (ApplicationAdapter.Instance.Platform
is RuntimePlatform.PS4
or RuntimePlatform.PS5)
{
operatingSystemContext.Name = "PlayStation";
}
else
{
operatingSystemContext.RawDescription = MainThreadData.OperatingSystem;
Expand Down
2 changes: 2 additions & 0 deletions src/Sentry.Unity/ScriptableSentryUnityOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public static string GetConfigPath(string? notDefaultConfigName = null)
[field: SerializeField] public bool MacosNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public bool LinuxNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public bool XboxNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public bool PlayStationNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public bool Il2CppLineNumberSupportEnabled { get; set; } = true;
[field: SerializeField] public SentryOptionsConfiguration? OptionsConfiguration { get; set; }

Expand Down Expand Up @@ -191,6 +192,7 @@ internal SentryUnityOptions ToSentryUnityOptions(
MacosNativeSupportEnabled = MacosNativeSupportEnabled,
LinuxNativeSupportEnabled = LinuxNativeSupportEnabled,
XboxNativeSupportEnabled = XboxNativeSupportEnabled,
PlayStationNativeSupportEnabled = PlayStationNativeSupportEnabled,
Il2CppLineNumberSupportEnabled = Il2CppLineNumberSupportEnabled,
PerformanceAutoInstrumentationEnabled = AutoAwakeTraces,
EnableLogs = EnableStructuredLogging,
Expand Down
19 changes: 15 additions & 4 deletions src/Sentry.Unity/SentryUnityOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@ public sealed class SentryUnityOptions : SentryOptions
/// </summary>
public bool XboxNativeSupportEnabled { get; set; } = true;

/// <summary>
/// Whether the SDK should add native support for PlayStation
/// </summary>
public bool PlayStationNativeSupportEnabled { get; set; } = true;

/// <summary>
/// Whether the SDK should add IL2CPP line number support
/// </summary>
Expand Down Expand Up @@ -365,8 +370,11 @@ internal SentryUnityOptions(IApplication? application = null,
application ??= ApplicationAdapter.Instance;
behaviour ??= SentryMonoBehaviour.Instance;

// IL2CPP doesn't support Process.GetCurrentProcess().StartupTime
DetectStartupTime = StartupTimeDetectionMode.Fast;
DetectStartupTime = application.Platform is RuntimePlatform.PS4 or RuntimePlatform.PS5
// PlayStation doesn't support startup time
? StartupTimeDetectionMode.None
// IL2CPP doesn't support Process.GetCurrentProcess().StartupTime
: StartupTimeDetectionMode.Fast;

AddInAppExclude("UnityEngine");
AddInAppExclude("UnityEditor");
Expand Down Expand Up @@ -428,7 +436,8 @@ or RuntimePlatform.OSXPlayer or RuntimePlatform.OSXServer

// Consoles: false
RuntimePlatform.GameCoreXboxSeries or RuntimePlatform.GameCoreXboxOne
or RuntimePlatform.PS4 or RuntimePlatform.PS5 or RuntimePlatform.Switch => false,
or RuntimePlatform.PS4 or RuntimePlatform.PS5
or RuntimePlatform.Switch => false,

// Unknown platforms
_ => false
Expand Down Expand Up @@ -492,7 +501,9 @@ or RuntimePlatform.LinuxPlayer
or RuntimePlatform.LinuxServer
or RuntimePlatform.WebGLPlayer
or RuntimePlatform.GameCoreXboxSeries
or RuntimePlatform.GameCoreXboxOne;
or RuntimePlatform.GameCoreXboxOne
or RuntimePlatform.PS4
or RuntimePlatform.PS5;
}

public override string ToString()
Expand Down
1 change: 1 addition & 0 deletions src/Sentry.Unity/SentryUnityOptionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ internal static bool IsNativeSupportEnabled(this SentryUnityOptions options, Run
RuntimePlatform.OSXPlayer or RuntimePlatform.OSXServer => options.MacosNativeSupportEnabled,
RuntimePlatform.LinuxPlayer or RuntimePlatform.LinuxServer => options.LinuxNativeSupportEnabled,
RuntimePlatform.GameCoreXboxSeries or RuntimePlatform.GameCoreXboxOne => options.XboxNativeSupportEnabled,
RuntimePlatform.PS4 or RuntimePlatform.PS5 => options.PlayStationNativeSupportEnabled,
_ => false
};
}
Expand Down
26 changes: 26 additions & 0 deletions test/Sentry.Unity.Tests/SentryUnityOptionsExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using NUnit.Framework;
using Sentry.Unity.Tests.Stubs;
using UnityEngine;

namespace Sentry.Unity.Tests;

Expand Down Expand Up @@ -183,4 +184,29 @@ public void DisableUnhandledExceptionCapture_DoesNotRemoveUnityApplicationLoggin

Assert.IsTrue(options.Integrations.Any(i => i is Integrations.UnityApplicationLoggingIntegration));
}

[Test]
[TestCase(RuntimePlatform.PS4, true, true)]
[TestCase(RuntimePlatform.PS4, false, false)]
[TestCase(RuntimePlatform.PS5, true, true)]
[TestCase(RuntimePlatform.PS5, false, false)]
[TestCase(RuntimePlatform.GameCoreXboxSeries, true, true)]
[TestCase(RuntimePlatform.GameCoreXboxSeries, false, false)]
[TestCase(RuntimePlatform.GameCoreXboxOne, true, true)]
[TestCase(RuntimePlatform.GameCoreXboxOne, false, false)]
public void IsNativeSupportEnabled_ConsolePlatforms_ReturnsExpectedValue(
RuntimePlatform platform, bool optionEnabled, bool expectedResult)
{
var options = _fixture.GetSut();
options.PlayStationNativeSupportEnabled = platform is RuntimePlatform.PS4 or RuntimePlatform.PS5
? optionEnabled
: options.PlayStationNativeSupportEnabled;
options.XboxNativeSupportEnabled = platform is RuntimePlatform.GameCoreXboxSeries or RuntimePlatform.GameCoreXboxOne
? optionEnabled
: options.XboxNativeSupportEnabled;

var result = options.IsNativeSupportEnabled(platform);

Assert.AreEqual(expectedResult, result);
}
}
Loading