Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ jobs:
host: ubuntu-latest
- target: Windows
host: windows-latest
- target: WindowsNative
host: windows-latest
- target: Cocoa
host: macos-latest
uses: ./.github/workflows/sdk.yml
Expand Down
18 changes: 17 additions & 1 deletion .github/workflows/sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,23 @@ jobs:
retention-days: 14

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ env.TARGET != 'Cocoa' }}
if: ${{ env.TARGET == 'Windows' }}
with:
name: ${{ env.TARGET }}-sdk
path: package-dev/Plugins/Windows/Sentry~
# Lower retention period - we only need this to retry CI.
retention-days: 14

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ env.TARGET == 'WindowsNative' }}
with:
name: ${{ env.TARGET }}-sdk
path: package-dev/Plugins/Windows/SentryNative~
# Lower retention period - we only need this to retry CI.
retention-days: 14

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ env.TARGET != 'Cocoa' && env.TARGET != 'Windows' && env.TARGET != 'WindowsNative' }}
with:
name: ${{ env.TARGET }}-sdk
path: package-dev/Plugins/${{ env.TARGET }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ modules/sentry-native-ndk
# Android SDK files
package-dev/Plugins/Android/Sentry~/*

# Windows SDK files
package-dev/Plugins/Windows/Sentry~/*
package-dev/Plugins/Windows/SentryNative~/*

# CLI
package-dev/Editor/sentry-cli

Expand Down
64 changes: 61 additions & 3 deletions build/native-sdks.targets
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
<!-- Native (Windows / Linux) -->
<SentryNativeRoot>$(RepoRoot)modules/sentry-native/</SentryNativeRoot>
<SentryLinuxArtifactsDestination>$(SentryArtifactsDestination)Linux/Sentry/</SentryLinuxArtifactsDestination>
<SentryWindowsArtifactsDestination>$(SentryArtifactsDestination)Windows/Sentry/</SentryWindowsArtifactsDestination>
<SentryWindowsArtifactsDestination>$(SentryArtifactsDestination)Windows/Sentry~/</SentryWindowsArtifactsDestination>
<SentryWindowsNativeArtifactsDestination>$(SentryArtifactsDestination)Windows/SentryNative~/</SentryWindowsNativeArtifactsDestination>
</PropertyGroup>

<!--
Expand Down Expand Up @@ -102,17 +103,23 @@
<!-- Wipe prior outputs -->
<RemoveDir Directories="$(SentryNativeRoot)build" ContinueOnError="true" />
<Delete Files="$(SentryWindowsArtifactsDestination)crashpad_handler.exe" ContinueOnError="true" />
<Delete Files="$(SentryWindowsArtifactsDestination)crashpad_handler.pdb" ContinueOnError="true" />
<Delete Files="$(SentryWindowsArtifactsDestination)crashpad_wer.dll" ContinueOnError="true" />
<Delete Files="$(SentryWindowsArtifactsDestination)crashpad_wer.pdb" ContinueOnError="true" />
<Delete Files="$(SentryWindowsArtifactsDestination)sentry.dll" ContinueOnError="true" />
<Delete Files="$(SentryWindowsArtifactsDestination)sentry.pdb" ContinueOnError="true" />

<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake -B build -D SENTRY_BACKEND=crashpad -D SENTRY_SDK_NAME=sentry.native.unity -D SENTRY_BUILD_RUNTIMESTATIC=ON -S ." />
<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake --build build --target sentry --config RelWithDebInfo --parallel" />
<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake --build build --target crashpad_handler --config Release --parallel" />
<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake --build build --target crashpad_handler --config RelWithDebInfo --parallel" />

<MakeDir Directories="$(SentryWindowsArtifactsDestination)" />

<ItemGroup>
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/crashpad_build/handler/Release/crashpad_handler.exe" />
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/crashpad_build/handler/RelWithDebInfo/crashpad_handler.exe" />
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/crashpad_build/handler/RelWithDebInfo/crashpad_handler.pdb" />
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/crashpad_build/handler/RelWithDebInfo/crashpad_wer.dll" />
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/crashpad_build/handler/RelWithDebInfo/crashpad_wer.pdb" />
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/RelWithDebInfo/sentry.dll" />
<NativeSdkArtifacts Include="$(SentryNativeRoot)build/RelWithDebInfo/sentry.pdb" />
</ItemGroup>
Expand All @@ -131,6 +138,57 @@
<CallTarget Targets="BuildWindowsSDK" />
</Target>

<!--
Build the Sentry Native SDK for Windows (sentry-native's new native backend):
dotnet msbuild /t:BuildWindowsNativeSDK src/Sentry.Unity
Always wipes prior outputs and rebuilds. Produces sentry.dll, sentry-crash.exe,
and sentry-wer.dll plus their .pdb sidecars.
-->
<Target Name="BuildWindowsNativeSDK" Condition="'$(MSBuildProjectName)' == 'Sentry.Unity'">
<Error Condition="!$([MSBuild]::IsOSPlatform('Windows'))" Text="BuildWindowsNativeSDK can only run on Windows." />
<Error Condition="!Exists('$(SentryNativeRoot)')" Text="sentry-native submodule not checked out at $(SentryNativeRoot). Run: git submodule update --init modules/sentry-native" />

<Message Importance="High" Text="Building Sentry Native SDK for Windows (native backend, clean rebuild)." />

<!-- Wipe prior outputs -->
<RemoveDir Directories="$(SentryNativeRoot)build_native" ContinueOnError="true" />
<Delete Files="$(SentryWindowsNativeArtifactsDestination)sentry.dll" ContinueOnError="true" />
<Delete Files="$(SentryWindowsNativeArtifactsDestination)sentry.pdb" ContinueOnError="true" />
<Delete Files="$(SentryWindowsNativeArtifactsDestination)sentry-crash.exe" ContinueOnError="true" />
<Delete Files="$(SentryWindowsNativeArtifactsDestination)sentry-crash.pdb" ContinueOnError="true" />
<Delete Files="$(SentryWindowsNativeArtifactsDestination)sentry-wer.dll" ContinueOnError="true" />
<Delete Files="$(SentryWindowsNativeArtifactsDestination)sentry-wer.pdb" ContinueOnError="true" />

<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake -B build_native -D SENTRY_BACKEND=native -D SENTRY_SDK_NAME=sentry.native.unity -D SENTRY_BUILD_RUNTIMESTATIC=ON -S ." />
<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake --build build_native --target sentry --config RelWithDebInfo --parallel" />
<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake --build build_native --target sentry-crash --config RelWithDebInfo --parallel" />
<Exec WorkingDirectory="$(SentryNativeRoot)" Command="cmake --build build_native --target sentry-wer --config RelWithDebInfo --parallel" />

<MakeDir Directories="$(SentryWindowsNativeArtifactsDestination)" />

<ItemGroup>
<WindowsNativeSdkArtifacts Include="$(SentryNativeRoot)build_native/RelWithDebInfo/sentry.dll" />
<WindowsNativeSdkArtifacts Include="$(SentryNativeRoot)build_native/RelWithDebInfo/sentry.pdb" />
<WindowsNativeSdkArtifacts Include="$(SentryNativeRoot)build_native/RelWithDebInfo/sentry-crash.exe" />
<WindowsNativeSdkArtifacts Include="$(SentryNativeRoot)build_native/RelWithDebInfo/sentry-crash.pdb" />
<WindowsNativeSdkArtifacts Include="$(SentryNativeRoot)build_native/RelWithDebInfo/sentry-wer.dll" />
<WindowsNativeSdkArtifacts Include="$(SentryNativeRoot)build_native/RelWithDebInfo/sentry-wer.pdb" />
</ItemGroup>

<Copy SourceFiles="@(WindowsNativeSdkArtifacts)" DestinationFolder="$(SentryWindowsNativeArtifactsDestination)" />

<Error Condition="!Exists('$(SentryWindowsNativeArtifactsDestination)sentry.dll')" Text="Failed to set up the Windows Native SDK." />
</Target>

<!-- Hooks into 'dotnet build' so a missing Windows Native plugin auto-triggers BuildWindowsNativeSDK. -->
<Target Name="EnsureWindowsNativeSDK"
BeforeTargets="BeforeBuild"
Condition="'$(MSBuildProjectName)' == 'Sentry.Unity'
And $([MSBuild]::IsOSPlatform('Windows'))
And !Exists('$(SentryWindowsNativeArtifactsDestination)sentry.dll')">
<CallTarget Targets="BuildWindowsNativeSDK" />
</Target>

<!--
Build sentry-native-ndk and publish it to the local Maven repo (~/.m2)
so sentry-java's :sentry-android-ndk build can resolve it via mavenLocal().
Expand Down
90 changes: 0 additions & 90 deletions package-dev/Plugins/Windows/Sentry/sentry.dll.meta

This file was deleted.

9 changes: 7 additions & 2 deletions scripts/download-native-sdks.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ $ArtifactsDestination = Join-Path $RepoRoot "package-dev/Plugins"
$SDKs = @(
@{
Name = "Windows"
Destination = Join-Path $ArtifactsDestination "Windows"
CheckFile = "Sentry/sentry.dll"
Destination = Join-Path $ArtifactsDestination "Windows/Sentry~"
CheckFile = "sentry.dll"
},
@{
Name = "WindowsNative"
Destination = Join-Path $ArtifactsDestination "Windows/SentryNative~"
CheckFile = "sentry.dll"
},
@{
Name = "Linux"
Expand Down
13 changes: 13 additions & 0 deletions src/Sentry.Unity.Editor/ConfigurationWindow/AdvancedTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,19 @@ internal static void Display(ScriptableSentryUnityOptions options, SentryCliOpti
new GUIContent("Windows", "Whether to enable native crashes support on Windows."),
options.WindowsNativeSupportEnabled);

EditorGUI.indentLevel++;
using (new EditorGUI.DisabledScope(!options.WindowsNativeSupportEnabled))
{
options.WindowsBackend = (WindowsBackend)EditorGUILayout.EnumPopup(
new GUIContent(
"Windows Backend",
"Crashpad: ships crashpad_handler.exe as the out-of-process handler.\n" +
"Native (experimental): uses sentry-native's new out-of-process sentry-crash.exe daemon. " +
"Uploads crashes immediately."),
options.WindowsBackend);
}
EditorGUI.indentLevel--;

options.MacosNativeSupportEnabled = EditorGUILayout.Toggle(
new GUIContent("macOS", "Whether to enable native crashes support on macOS."),
options.MacosNativeSupportEnabled);
Expand Down
58 changes: 47 additions & 11 deletions src/Sentry.Unity.Editor/Native/BuildPostProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ and not BuildTargetGroup.PS5
try
{
AddCrashHandler(logger, target, buildOutputDir);
if (target is BuildTarget.StandaloneWindows or BuildTarget.StandaloneWindows64)
{
CopyWindowsPlugins(logger, options, buildOutputDir);
}
}
catch (Exception e)
{
Expand All @@ -114,10 +118,8 @@ private static void AddCrashHandler(IDiagnosticLogger logger, BuildTarget target
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
logger.LogDebug("Adding crashpad.");
CopyHandler(logger, buildOutputDir, Path.Combine("Windows", "Sentry", "crashpad_handler.exe"));
CopyHandler(logger, buildOutputDir, Path.Combine("Windows", "Sentry", "crashpad_wer.dll"));
break;
// Handled by CopyWindowsPlugins.
return;
case BuildTarget.StandaloneLinux64:
case BuildTarget.StandaloneOSX:
// No standalone crash handler for Linux/macOS - uses built-in handlers.
Expand All @@ -137,12 +139,33 @@ private static void AddCrashHandler(IDiagnosticLogger logger, BuildTarget target
}
}

private static void CopyHandler(IDiagnosticLogger logger, string buildOutputDir, string handlerPath)
private static void CopyWindowsPlugins(IDiagnosticLogger logger, SentryUnityOptions options, string buildOutputDir)
{
var fullHandlerPath = Path.GetFullPath(Path.Combine("Packages", SentryPackageInfo.GetName(), "Plugins", handlerPath));
var targetHandlerPath = Path.Combine(buildOutputDir, Path.GetFileName(fullHandlerPath));
logger.LogInfo("Copying handler '{0}' to {1}", Path.GetFileName(fullHandlerPath), targetHandlerPath);
File.Copy(fullHandlerPath, targetHandlerPath, true);
var packagePluginsDir = Path.GetFullPath($"Packages/{SentryPackageInfo.GetName()}/Plugins/Windows");
var sourceDir = options.WindowsBackend == WindowsBackend.Native
? Path.Combine(packagePluginsDir, "SentryNative~")
: Path.Combine(packagePluginsDir, "Sentry~");

if (!Directory.Exists(sourceDir))
{
var target = options.WindowsBackend == WindowsBackend.Native ? "BuildWindowsNativeSDK" : "BuildWindowsSDK";
throw new BuildFailedException(
$"Sentry Windows plugin directory not found: {sourceDir}\n" +
$"Run 'dotnet msbuild /t:{target} src/Sentry.Unity' (or 'dotnet msbuild /t:DownloadNativeSDKs src/Sentry.Unity') to populate it.");
}

// Flat copy of every non-PDB file next to the player .exe.
// PDBs stay in the package and are consumed at symbol-upload time only.
foreach (var file in Directory.GetFiles(sourceDir))
{
if (file.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var destFile = Path.Combine(buildOutputDir, Path.GetFileName(file));
logger.LogDebug("Copying '{0}' to '{1}'", file, destFile);
File.Copy(file, destFile, overwrite: true);
}
}

internal static void AddPath(List<string> paths, string path, IDiagnosticLogger logger, bool required = false)
Expand Down Expand Up @@ -199,8 +222,21 @@ private static void UploadDebugSymbols(IDiagnosticLogger logger, BuildTarget tar
AddPath(paths, Path.Combine(buildOutputDir, executableName), logger, required: true);
AddPath(paths, Path.Combine(buildOutputDir, "UnityPlayer.dll"), logger, required: true);

// Sentry native SDK symbols from package
AddPath(paths, Path.GetFullPath($"Packages/{SentryPackageInfo.GetName()}/Plugins/Windows/Sentry/sentry.pdb"), logger);
// Sentry native SDK symbols from package.
// Glob *.pdb from whichever backend's source dir is in use, so adding
// or removing PDBs at build time doesn't require touching this code.
var windowsBackendDir = options.WindowsBackend == WindowsBackend.Native
? "SentryNative~"
: "Sentry~";
var windowsPdbDir = Path.GetFullPath(
$"Packages/{SentryPackageInfo.GetName()}/Plugins/Windows/{windowsBackendDir}");
if (Directory.Exists(windowsPdbDir))
{
foreach (var pdb in Directory.GetFiles(windowsPdbDir, "*.pdb"))
{
AddPath(paths, pdb, logger);
}
}

// Data - native plugins
foreach (var dir in Directory.GetDirectories(buildOutputDir, "*_Data"))
Expand Down
7 changes: 7 additions & 0 deletions src/Sentry.Unity.Native/SentryNativeBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ is RuntimePlatform.WindowsPlayer or RuntimePlatform.WindowsServer
Logger?.LogDebug("Setting EnableMetrics: {0}", options.EnableMetrics);
sentry_options_set_enable_metrics(cOptions, options.EnableMetrics ? 1 : 0);

var shutdownMs = (ulong)Math.Max(0, options.ShutdownTimeout.TotalMilliseconds);
Logger?.LogDebug("Setting ShutdownTimeout: {0} ms", shutdownMs);
sentry_options_set_shutdown_timeout(cOptions, shutdownMs);

if (options.UnityInfo.IL2CPP)
{
Logger?.LogDebug("Setting the native logger");
Expand Down Expand Up @@ -178,6 +182,9 @@ internal static string GetDatabasePath(SentryUnityOptions options, IApplication?
[DllImport(SentryLib)]
private static extern void sentry_options_set_enable_metrics(IntPtr options, int enable_metrics);

[DllImport(SentryLib)]
private static extern void sentry_options_set_shutdown_timeout(IntPtr options, ulong shutdown_timeout);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, SetLastError = true)]
private delegate void sentry_logger_function_t(int level, IntPtr message, IntPtr argsAddress, IntPtr userData);

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 @@ -124,6 +124,7 @@ public static string GetConfigPath(string? notDefaultConfigName = null)
[field: SerializeField] public bool NdkScopeSyncEnabled { get; set; } = true;
[field: SerializeField] public int PostGenerateGradleProjectCallbackOrder { get; set; } = 1;
[field: SerializeField] public bool WindowsNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public WindowsBackend WindowsBackend { get; set; } = WindowsBackend.Crashpad;
[field: SerializeField] public bool MacosNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public bool LinuxNativeSupportEnabled { get; set; } = true;
[field: SerializeField] public bool XboxNativeSupportEnabled { get; set; } = true;
Expand Down Expand Up @@ -209,6 +210,7 @@ internal SentryUnityOptions ToSentryUnityOptions(
NdkScopeSyncEnabled = NdkScopeSyncEnabled,
PostGenerateGradleProjectCallbackOrder = PostGenerateGradleProjectCallbackOrder,
WindowsNativeSupportEnabled = WindowsNativeSupportEnabled,
WindowsBackend = WindowsBackend,
MacosNativeSupportEnabled = MacosNativeSupportEnabled,
LinuxNativeSupportEnabled = LinuxNativeSupportEnabled,
XboxNativeSupportEnabled = XboxNativeSupportEnabled,
Expand Down
Loading
Loading