Skip to content
Open
Show file tree
Hide file tree
Changes from 12 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
20 changes: 20 additions & 0 deletions package-dev/Plugins/PS5/sentry_utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdio.h>

/**
* Wrapper around vsnprintf for Unity C# IL2CPP interop.
*
* This function provides a stable ABI entry point for Unity to call
* vsnprintf functionality on PlayStation platforms. IL2CPP cannot directly
* call the vsnprintf from the Prospero SDK because:
* 1. IL2CPP generates a forward declaration with generic pointer types
* 2. This conflicts with the actual vsnprintf signature in stdio.h
* 3. va_list requires proper platform-specific handling
*
* This wrapper is compiled as native C code where va_list is properly
* understood, then IL2CPP calls this wrapper with generic pointers.
*/
int vsnprintf_ps(char *buffer, size_t size, const char *format, va_list args)
{
return vsnprintf(buffer, size, format, args);
}
83 changes: 30 additions & 53 deletions package-dev/Runtime/Sentry.Unity.Native.dll.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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
18 changes: 16 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,9 @@ 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.PS5)
{
return;
}
Expand Down Expand Up @@ -47,10 +48,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.PS5 => executablePath,
_ => string.Empty
};

Expand Down Expand Up @@ -87,6 +90,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.PS5 => options.PlayStationNativeSupportEnabled,
_ => false,
};

Expand All @@ -108,6 +112,9 @@ private static void AddCrashHandler(IDiagnosticLogger logger, BuildTarget target
case BuildTarget.GameCoreXboxOne:
// No standalone crash handler for Xbox - comes with Breakpad
return;
case BuildTarget.PS5:
// No standalone crash handler for PlayStation
return;
default:
throw new ArgumentException($"Unsupported build target: {target}");
}
Expand Down Expand Up @@ -158,6 +165,13 @@ private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget tar
paths += $" \"{xboxSentryPluginPath}\"";
}
break;
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
1 change: 0 additions & 1 deletion src/Sentry.Unity.Native/SentryNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ private static void ReinstallBackend()
switch (application.Platform)
{
case RuntimePlatform.Switch:
case RuntimePlatform.PS4:
case RuntimePlatform.PS5:
case RuntimePlatform.XboxOne:
case RuntimePlatform.GameCoreXboxSeries:
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.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.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("__Internal")]
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
4 changes: 3 additions & 1 deletion src/Sentry.Unity/Il2CppEventProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ or RuntimePlatform.LinuxServer
or RuntimePlatform.WindowsPlayer
or RuntimePlatform.WindowsServer
or RuntimePlatform.GameCoreXboxSeries
or RuntimePlatform.GameCoreXboxOne;
or RuntimePlatform.GameCoreXboxOne
or RuntimePlatform.PS5;
}

private string GetPlatformDebugImageType(RuntimePlatform? platform = null)
Expand All @@ -373,6 +374,7 @@ private string GetPlatformDebugImageType(RuntimePlatform? platform = null)
case RuntimePlatform.Android:
case RuntimePlatform.LinuxPlayer:
case RuntimePlatform.LinuxServer:
case RuntimePlatform.PS5:
return "elf";
case RuntimePlatform.IPhonePlayer:
case RuntimePlatform.OSXPlayer:
Expand Down
4 changes: 4 additions & 0 deletions src/Sentry.Unity/Integrations/UnityScopeIntegration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ is RuntimePlatform.GameCoreXboxSeries
{
operatingSystemContext.Name = "Xbox";
}
else if (ApplicationAdapter.Instance.Platform is RuntimePlatform.PS5)
{
operatingSystemContext.Name = "PlayStation";
}
else
{
operatingSystemContext.RawDescription = MainThreadData.OperatingSystem;
Expand Down
Loading
Loading