Skip to content
Merged
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
12 changes: 12 additions & 0 deletions .github/alpine/setup-node.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

[ -n "$1" ] || { echo "Usage: $0 <path>"; exit 1; }

# A workaround for "JavaScript Actions in Alpine containers are only supported on x64 Linux runners."
# https://github.com/actions/runner/blob/8a9b96806d12343f7d123c669e29c629138023dd/src/Runner.Worker/Handlers/StepHost.cs#L283-L290
if [ "$(uname -m)" != "x86_64" ]; then
mkdir -p $1
ln -s /usr/bin/node $1
ln -s /usr/bin/npm $1
sed -i 's/ID=alpine/ID=unknown/' /usr/lib/os-release
fi
32 changes: 32 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ jobs:
rid: linux-musl-x64
container:
image: ghcr.io/getsentry/sentry-dotnet-alpine:3.21
- os: ubuntu-24.04-arm
rid: linux-musl-arm64
container:
image: ghcr.io/getsentry/sentry-dotnet-alpine:3.21
volumes:
- /tmp/node20:/__e/node20
- os: macos-15 # Pin macos to get the version of Xcode that we need: https://github.com/actions/runner-images/issues/10703
rid: macos # universal (osx-arm64 + osx-x64)
- os: windows-latest
Expand All @@ -35,6 +41,11 @@ jobs:
rid: win-arm64

steps:
- name: Initialize Alpine Linux
if: ${{ contains(matrix.container.image, 'alpine') }}
run: |
curl -sSL https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/.github/alpine/setup-node.sh | sudo bash /dev/stdin /__e/node20/bin/

- name: Checkout
uses: actions/checkout@v4

Expand Down Expand Up @@ -83,6 +94,14 @@ jobs:
image: ghcr.io/getsentry/sentry-dotnet-alpine:3.21
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- os: ubuntu-24.04-arm
rid: linux-musl-arm64
slnf: Sentry-CI-Build-Linux-musl.slnf
container:
image: ghcr.io/getsentry/sentry-dotnet-alpine:3.21
volumes:
- /tmp/node20:/__e/node20
- /var/run/docker.sock:/var/run/docker.sock
- os: macos-15 # Pin macos to get the version of Xcode that we need: https://github.com/actions/runner-images/issues/10703
rid: macos # universal (osx-arm64 + osx-x64)
slnf: Sentry-CI-Build-macOS.slnf
Expand All @@ -94,6 +113,11 @@ jobs:
slnf: Sentry-CI-Build-Windows-arm64.slnf

steps:
- name: Initialize Alpine Linux
if: ${{ contains(matrix.container.image, 'alpine') }}
run: |
curl -sSL https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/.github/alpine/setup-node.sh | sudo bash /dev/stdin /__e/node20/bin/

- name: Cancel Previous Runs
if: github.ref_name != 'main' && !startsWith(github.ref_name, 'release/')
uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # Tag: 0.12.1
Expand Down Expand Up @@ -140,6 +164,14 @@ jobs:
key: sentry-native-linux-musl-x64-${{ hashFiles('scripts/build-sentry-native.ps1') }}-${{ hashFiles('.git/modules/modules/sentry-native/HEAD') }}
fail-on-cache-miss: true

- name: Download sentry-native (linux-musl-arm64)
if: ${{ (env.CI_PUBLISHING_BUILD == 'true') || (matrix.rid == 'linux-musl-arm64') }}
uses: actions/cache/restore@v4
with:
path: src/Sentry/Platforms/Native/sentry-native
key: sentry-native-linux-musl-arm64-${{ hashFiles('scripts/build-sentry-native.ps1') }}-${{ hashFiles('.git/modules/modules/sentry-native/HEAD') }}
fail-on-cache-miss: true

- name: Download sentry-native (macos)
if: ${{ (env.CI_PUBLISHING_BUILD == 'true') || (matrix.rid == 'macos') }}
uses: actions/cache/restore@v4
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Native AOT: don't load SentryNative on unsupported platforms ([#4347](https://github.com/getsentry/sentry-dotnet/pull/4347))
- Fixed issue introduced in release 5.12.0 that might prevent other middleware or user code from reading request bodies ([#4373](https://github.com/getsentry/sentry-dotnet/pull/4373))
- SentryTunnelMiddleware overwrites the X-Forwarded-For header ([#4375](https://github.com/getsentry/sentry-dotnet/pull/4375))
- Native AOT support for `linux-musl-arm64` ([#4365](https://github.com/getsentry/sentry-dotnet/pull/4365))

### Dependencies

Expand Down
10 changes: 8 additions & 2 deletions integration-test/runtime.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,17 @@ internal class FakeTransport : ITransport
}
else
{
if ("Arm64".Equals([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()))
$musl = (ldd --version 2>&1) -match 'musl'
$arm64 = "Arm64".Equals([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString())
if ($musl -and $arm64)
{
return "./console-app/bin/Release/$framework/linux-musl-arm64/publish/console-app"
}
elseif ($arm64)
{
return "./console-app/bin/Release/$framework/linux-arm64/publish/console-app"
}
elseif ((ldd --version 2>&1) -match 'musl')
elseif ($musl)
{
return "./console-app/bin/Release/$framework/linux-musl-x64/publish/console-app"
}
Expand Down
10 changes: 8 additions & 2 deletions scripts/build-sentry-native.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ try
}
elseif ($IsLinux)
{
if ("Arm64".Equals([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()))
$musl = (ldd --version 2>&1) -match 'musl'
$arm64 = "Arm64".Equals([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString())
if ($musl -and $arm64)
{
$outDir += '/linux-musl-arm64'
}
elseif ($arm64)
{
$outDir += '/linux-arm64'
}
elseif ((ldd --version 2>&1) -match 'musl')
elseif ($musl)
{
$outDir += '/linux-musl-x64'
}
Expand Down
56 changes: 40 additions & 16 deletions src/Sentry/Platforms/Native/CFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ internal static void SetValueIfNotNull(sentry_value_t obj, string key, double? v

public static bool Init(SentryOptions options)
{
_isWindows = System.OperatingSystem.IsWindows();
var cOptions = sentry_options_new();

// Note: DSN is not null because options.IsValid() must have returned true for this to be called.
Expand Down Expand Up @@ -441,7 +440,9 @@ private static void nativeTransportFree(IntPtr state)

// The logger we should forward native messages to. This is referenced by nativeLog() which in turn for.
private static IDiagnosticLogger? _logger;
private static bool _isWindows = false;
private static bool _isWindows = System.OperatingSystem.IsWindows();
private static bool _isLinux = System.OperatingSystem.IsLinux();
private static bool _isArm64 = RuntimeInformation.OSArchitecture == Architecture.Arm64;

// This method is called from the C library and forwards incoming messages to the currently set _logger.
// [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })] // error CS3016: Arrays as attribute arguments is not CLS-complian
Expand Down Expand Up @@ -495,21 +496,14 @@ private static void nativeLogImpl(int cLevel, IntPtr format, IntPtr args, IntPtr
message = Marshal.PtrToStringAnsi(buffer);
});
}
// For Linux/macOS, we must make a copy of the VaList to be able to pass it back...
else if (_isLinux && _isArm64)
{
message = FormatWithVaList<VaListArm64>(format, args);
}
else
{
// For Linux/macOS, we must make a copy of the VaList to be able to pass it back...
var argsStruct = Marshal.PtrToStructure<VaListLinux64>(args);
var formattedLength = 0;
WithMarshalledStruct(argsStruct, argsPtr =>
formattedLength = 1 + vsnprintf_linux(IntPtr.Zero, UIntPtr.Zero, format, argsPtr)
);

WithAllocatedPtr(formattedLength, buffer =>
WithMarshalledStruct(argsStruct, argsPtr =>
{
vsnprintf_linux(buffer, (UIntPtr)formattedLength, format, argsPtr);
message = Marshal.PtrToStringAnsi(buffer);
}));
message = FormatWithVaList<VaListX64>(format, args);
}
}
catch (Exception err)
Expand All @@ -534,14 +528,25 @@ private static void nativeLogImpl(int cLevel, IntPtr format, IntPtr args, IntPtr

// https://stackoverflow.com/a/4958507/2386130
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct VaListLinux64
private struct VaListX64
{
private uint _gp_offset;
private uint _fp_offset;
private IntPtr _overflow_arg_area;
private IntPtr _reg_save_area;
}

// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#definition-of-va-list
[StructLayout(LayoutKind.Sequential)]
private struct VaListArm64
{
private IntPtr __stack;
private IntPtr __gr_top;
private IntPtr __vr_top;
private int __gr_offs;
private int __vr_offs;
}

private static void WithAllocatedPtr(int size, Action<IntPtr> action)
{
var ptr = IntPtr.Zero;
Expand All @@ -562,4 +567,23 @@ private static void WithMarshalledStruct<T>(T structure, Action<IntPtr> action)
Marshal.StructureToPtr(structure, ptr, false);
action(ptr);
});

private static string? FormatWithVaList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(IntPtr format, IntPtr args) where T : struct
{
string? message = null;
var argsStruct = Marshal.PtrToStructure<T>(args);
var formattedLength = 0;
WithMarshalledStruct(argsStruct, argsPtr =>
formattedLength = 1 + vsnprintf_linux(IntPtr.Zero, UIntPtr.Zero, format, argsPtr)
);

WithAllocatedPtr(formattedLength, buffer =>
WithMarshalledStruct(argsStruct, argsPtr =>
{
vsnprintf_linux(buffer, (UIntPtr)formattedLength, format, argsPtr);
message = Marshal.PtrToStringAnsi(buffer);
}));

return message;
}
}
10 changes: 10 additions & 0 deletions src/Sentry/Platforms/Native/Sentry.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@
<SentryNativeOutputDirectory-linux-musl-x64>$(SentryNativeOutputDirectory)$(NativeLibRelativePath-linux-musl-x64)\</SentryNativeOutputDirectory-linux-musl-x64>
<NativeLibRelativePath-linux-arm64>linux-arm64</NativeLibRelativePath-linux-arm64>
<SentryNativeOutputDirectory-linux-arm64>$(SentryNativeOutputDirectory)$(NativeLibRelativePath-linux-arm64)\</SentryNativeOutputDirectory-linux-arm64>
<NativeLibRelativePath-linux-musl-arm64>linux-musl-arm64</NativeLibRelativePath-linux-musl-arm64>
<SentryNativeOutputDirectory-linux-musl-arm64>$(SentryNativeOutputDirectory)$(NativeLibRelativePath-linux-musl-arm64)\</SentryNativeOutputDirectory-linux-musl-arm64>
<NativeLibRelativePath-osx>osx</NativeLibRelativePath-osx>
<SentryNativeOutputDirectory-osx>$(SentryNativeOutputDirectory)$(NativeLibRelativePath-osx)\</SentryNativeOutputDirectory-osx>
<SentryNativeBuildOutputs Condition="'$(RuntimeIdentifier)' == 'win-x64'">$(SentryNativeOutputDirectory-win-x64)lib$(SentryNativeLibraryName).lib</SentryNativeBuildOutputs>
<SentryNativeBuildOutputs Condition="'$(RuntimeIdentifier)' == 'win-arm64'">$(SentryNativeOutputDirectory-win-arm64)lib$(SentryNativeLibraryName).lib</SentryNativeBuildOutputs>
<SentryNativeBuildOutputs Condition="'$(RuntimeIdentifier)' == 'linux-x64'">$(SentryNativeOutputDirectory-linux-x64)lib$(SentryNativeLibraryName).a</SentryNativeBuildOutputs>
<SentryNativeBuildOutputs Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64'">$(SentryNativeOutputDirectory-linux-musl-x64)lib$(SentryNativeLibraryName).a</SentryNativeBuildOutputs>
<SentryNativeBuildOutputs Condition="'$(RuntimeIdentifier)' == 'linux-arm64'">$(SentryNativeOutputDirectory-linux-arm64)lib$(SentryNativeLibraryName).a</SentryNativeBuildOutputs>
<SentryNativeBuildOutputs Condition="'$(RuntimeIdentifier)' == 'linux-musl-arm64'">$(SentryNativeOutputDirectory-linux-musl-arm64)lib$(SentryNativeLibraryName).a</SentryNativeBuildOutputs>
<SentryNativeBuildOutputs Condition="$([MSBuild]::IsOsPlatform('OSX'))">$(SentryNativeOutputDirectory-osx)lib$(SentryNativeLibraryName).a</SentryNativeBuildOutputs>
</PropertyGroup>

Expand Down Expand Up @@ -69,6 +72,13 @@
</None>
</ItemGroup>

<ItemGroup Condition="'$(CI_PUBLISHING_BUILD)' == 'true' or '$(NETCoreSdkRuntimeIdentifier)' == 'linux-musl-arm64'">
<None Include="$(SentryNativeOutputDirectory-linux-musl-arm64)lib$(SentryNativeLibraryName).a">
<Pack>true</Pack>
<PackagePath>\sentry-native\$(NativeLibRelativePath-linux-musl-arm64)</PackagePath>
</None>
</ItemGroup>

<ItemGroup Condition="'$(CI_PUBLISHING_BUILD)' == 'true' or $([MSBuild]::IsOsPlatform('OSX'))">
<None Include="$(SentryNativeOutputDirectory-osx)lib$(SentryNativeLibraryName).a">
<Pack>true</Pack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<!-- Windows -->
<FrameworkSupportsNative Condition="'$(RuntimeIdentifier)' == 'win-x64' or '$(RuntimeIdentifier)' == 'win-arm64'">true</FrameworkSupportsNative>
<!-- Linux -->
<FrameworkSupportsNative Condition="'$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64' or '$(RuntimeIdentifier)' == 'linux-musl-x64'">true</FrameworkSupportsNative>
<FrameworkSupportsNative Condition="'$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64' or '$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">true</FrameworkSupportsNative>
<!-- macOS -->
<FrameworkSupportsNative Condition="'$(RuntimeIdentifier)' == 'osx-x64' or '$(RuntimeIdentifier)' == 'osx-arm64'">true</FrameworkSupportsNative>
<!-- net8.0 or greater -->
Expand Down Expand Up @@ -52,11 +52,11 @@
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\sentry-native\$(RuntimeIdentifier)\libsentry-native.a" />
</ItemGroup>

<ItemGroup Condition="'$(FrameworkSupportsNative)' == 'true' and '$(RuntimeIdentifier)' == 'linux-musl-x64'">
<ItemGroup Condition="'$(FrameworkSupportsNative)' == 'true' and ('$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64')">
<DirectPInvoke Include="sentry-native" />
<!-- When musl is detected, static sentry-native links to static libunwind, which depends on liblzma -->
<LinkerArg Include="-Wl,-Bstatic -Wl,--whole-archive -lunwind -Wl,--no-whole-archive -llzma -Wl,-Bdynamic" />
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\sentry-native\linux-musl-x64\libsentry-native.a" />
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\sentry-native\$(RuntimeIdentifier)\libsentry-native.a" />
</ItemGroup>

<ItemGroup Condition="'$(FrameworkSupportsNative)' == 'true' and ('$(RuntimeIdentifier)' == 'osx-x64' or '$(RuntimeIdentifier)' == 'osx-arm64')">
Expand Down
Loading