Skip to content
Merged
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
12 changes: 0 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ jobs:
if: ${{ !matrix.container }}
uses: ./.github/actions/freediskspace

- name: Install build dependencies
if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Linux' && !matrix.container
run: |
sudo apt update
sudo apt install libcurl4-openssl-dev

- run: scripts/build-sentry-native.ps1
if: steps.cache.outputs.cache-hit != 'true'
shell: pwsh
Expand Down Expand Up @@ -239,12 +233,6 @@ jobs:
name: ${{ github.sha }}
path: src

- name: Install build dependencies
if: runner.os == 'Linux' && !matrix.container
run: |
sudo apt update
sudo apt install libcurl4-openssl-dev

- name: Setup Environment
uses: ./.github/actions/environment

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Features

- Rename MemoryInfo.AllocatedBytes to MemoryInfo.TotalAllocatedBytes ([#4243](https://github.com/getsentry/sentry-dotnet/pull/4243))
- Replace libcurl with .NET HttpClient for sentry-native ([#4222](https://github.com/getsentry/sentry-dotnet/pull/4222))

## 5.9.0

Expand Down
4 changes: 1 addition & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,13 @@ For big feature it's advised to raise an issue to discuss it first.

* [`pwsh`](https://github.com/PowerShell/PowerShell#get-powershell) Core version 6 or later on PATH.

* `CMake` on PATH. On Windows you can install the [C++ CMake tools for Windows](https://learn.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-170#installation). On macOS you can use your favourite package manager (e.g. `brew install cmake`).
* `CMake` on PATH. On Windows you can install the [C++ CMake tools for Windows](https://learn.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-170#installation). On macOS and Linux you can use your favourite package manager (e.g. `brew install cmake` or `apt install cmake`).

* On Windows:
- [.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) 4.6.2 or higher.
- `Sentry.DiagnosticSource.IntegrationTests.csproj` uses [SQL LocalDb](https://docs.microsoft.com/sql/database-engine/configure-windows/sql-server-express-localdb) - [download SQL LocalDB 2019](https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SqlLocalDB.msi). To avoid running these tests, unload `Sentry.DiagnosticSource.IntegrationTests.csproj` from the solution.
* On macOS/Linux
- [Mono 6 or higher](https://www.mono-project.com/download/stable) to run the unit tests on the `net4x` targets.
* On Linux
- **curl** and **zlib** libraries (e.g. on Ubuntu: libcurl4-openssl-dev, libz-dev) to build the [sentry-native](https://github.com/getsentry/sentry-native/) module.

## .NET MAUI Requirements

Expand Down
1 change: 1 addition & 0 deletions scripts/build-sentry-native.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ try
-D SENTRY_SDK_NAME=sentry.native.dotnet `
-D SENTRY_BUILD_SHARED_LIBS=0 `
-D SENTRY_BACKEND=inproc `
-D SENTRY_TRANSPORT=none `
$additionalArgs

cmake `
Expand Down
16 changes: 2 additions & 14 deletions src/Sentry/Http/HttpTransportBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,20 +187,8 @@ protected internal virtual HttpRequestMessage CreateRequest(Envelope envelope)
throw new InvalidOperationException("The DSN is expected to be set at this point.");
}

var dsn = Dsn.Parse(_options.Dsn);
var authHeader =
$"Sentry sentry_version={_options.SentryVersion}," +
$"sentry_client={SdkVersion.Instance.Name}/{SdkVersion.Instance.Version}," +
$"sentry_key={dsn.PublicKey}" +
(dsn.SecretKey is { } secretKey ? $",sentry_secret={secretKey}" : null);

return new HttpRequestMessage
{
RequestUri = dsn.GetEnvelopeEndpointUri(),
Method = HttpMethod.Post,
Headers = { { "X-Sentry-Auth", authHeader } },
Content = new EnvelopeHttpContent(envelope, _options.DiagnosticLogger, _clock)
};
var content = new EnvelopeHttpContent(envelope, _options.DiagnosticLogger, _clock);
return _options.CreateHttpRequest(content);
}

/// <summary>
Expand Down
63 changes: 63 additions & 0 deletions src/Sentry/Platforms/Native/CFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ public static bool Init(SentryOptions options)
}
}

unsafe
{
var cTransport = sentry_transport_new(&nativeTransport);
sentry_transport_set_state(cTransport, GCHandle.ToIntPtr(GCHandle.Alloc(options)));
sentry_transport_set_free_func(cTransport, &nativeTransportFree);
sentry_options_set_transport(cOptions, cTransport);
}

options.DiagnosticLogger?.LogDebug("Initializing sentry native");
return 0 == sentry_init(cOptions);
}
Expand Down Expand Up @@ -364,6 +372,61 @@ internal struct sentry_value_t
[DllImport("sentry-native")]
private static extern void sentry_options_set_auto_session_tracking(IntPtr options, int debug);

[DllImport("sentry-native")]
private static extern void sentry_options_set_transport(IntPtr options, IntPtr transport);

[DllImport("sentry-native")]
private static extern unsafe IntPtr sentry_transport_new(delegate* unmanaged/*[Cdecl]*/<IntPtr, IntPtr, void> sendFunc);

[DllImport("sentry-native")]
private static extern void sentry_transport_set_state(IntPtr transport, IntPtr state);

[DllImport("sentry-native")]
private static extern unsafe void sentry_transport_set_free_func(IntPtr transport, delegate* unmanaged/*[Cdecl]*/<IntPtr, void> freeFunc);

[DllImport("sentry-native")]
private static extern IntPtr sentry_envelope_serialize(IntPtr envelope, out UIntPtr sizeOut);

[DllImport("sentry-native")]
private static extern void sentry_envelope_free(IntPtr envelope);

[DllImport("sentry-native")]
internal static extern void sentry_free(IntPtr ptr);

[UnmanagedCallersOnly]
private static void nativeTransport(IntPtr envelope, IntPtr state)
{
var options = GCHandle.FromIntPtr(state).Target as SentryOptions;
try
{
if (options is not null)
{
var data = sentry_envelope_serialize(envelope, out var size);
using var content = new UnmanagedHttpContent(data, (int)size, options.DiagnosticLogger);

using var client = options.GetHttpClient();
using var request = options.CreateHttpRequest(content);
client.SendAsync(request).GetAwaiter().GetResult();
}
}
catch (Exception e)
{
// never allow an exception back to native code - it would crash the app
options?.DiagnosticLogger?.LogError(e, "Exception in native transport callback. The native envelope will not be sent.");
}
finally
{
sentry_envelope_free(envelope);
}
}

[UnmanagedCallersOnly]
private static void nativeTransportFree(IntPtr state)
{
var handle = GCHandle.FromIntPtr(state);
handle.Free();
}

[DllImport("sentry-native")]
private static extern unsafe void sentry_options_set_logger(IntPtr options, delegate* unmanaged/*[Cdecl]*/<int, IntPtr, IntPtr, IntPtr, void> logger, IntPtr userData);

Expand Down
62 changes: 62 additions & 0 deletions src/Sentry/Platforms/Native/UnmanagedHttpContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Sentry.Extensibility;

namespace Sentry.Native;

internal sealed class UnmanagedHttpContent : SerializableHttpContent
{
private readonly IntPtr _content;
private readonly int _length = 0;
private readonly IDiagnosticLogger? _logger;

public UnmanagedHttpContent(IntPtr content, int length, IDiagnosticLogger? logger)
{
_content = content;
_length = length;
_logger = logger;
}

protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context)
{
try
{
using var unmanagedStream = CreateStream();
await unmanagedStream.CopyToAsync(stream).ConfigureAwait(false);
}
catch (Exception e)
{
_logger?.LogError(e, "Failed to serialize unmanaged content into the network stream");
throw;
}
}

protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken)
{
try
{
using var unmanagedStream = CreateStream();
unmanagedStream.CopyTo(stream);
}
catch (Exception e)
{
_logger?.LogError(e, "Failed to serialize unmanaged content into the network stream");
throw;
}
}

protected override bool TryComputeLength(out long length)
{
length = _length;
return true;
}

protected override void Dispose(bool disposing)
{
C.sentry_free(_content);
base.Dispose(disposing);
}

private unsafe UnmanagedMemoryStream CreateStream()
{
return new UnmanagedMemoryStream((byte*)_content.ToPointer(), _length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
<ItemGroup Condition="'$(FrameworkSupportsNative)' == 'true' and ('$(RuntimeIdentifier)' == 'linux-x64' or '$(RuntimeIdentifier)' == 'linux-arm64')">
<DirectPInvoke Include="sentry-native" />
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\sentry-native\$(RuntimeIdentifier)\libsentry-native.a" />
<!-- See: https://github.com/dotnet/runtime/issues/97414 -->
<NativeSystemLibrary Include="curl" />
</ItemGroup>

<ItemGroup Condition="'$(FrameworkSupportsNative)' == 'true' and '$(RuntimeIdentifier)' == 'linux-musl-x64'">
Expand All @@ -46,13 +44,10 @@
<LinkerArg Include="-Wl,-Bstatic -Wl,--whole-archive -lunwind -Wl,--no-whole-archive -Wl,-Bdynamic" />
<NativeSystemLibrary Include="lzma" />
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\sentry-native\linux-musl-x64\libsentry-native.a" />
<!-- See: https://github.com/dotnet/runtime/issues/97414 -->
<NativeSystemLibrary Include="curl" />
</ItemGroup>

<ItemGroup Condition="'$(FrameworkSupportsNative)' == 'true' and ('$(RuntimeIdentifier)' == 'osx-x64' or '$(RuntimeIdentifier)' == 'osx-arm64')">
<DirectPInvoke Include="sentry-native" />
<NativeLibrary Include="$(MSBuildThisFileDirectory)..\sentry-native\osx\libsentry-native.a" />
<NativeSystemLibrary Include="curl" />
</ItemGroup>
</Project>
17 changes: 17 additions & 0 deletions src/Sentry/SentryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,23 @@ internal HttpClient GetHttpClient()
return factory.Create(this);
}

internal HttpRequestMessage CreateHttpRequest(HttpContent content)
{
var authHeader =
$"Sentry sentry_version={SentryVersion}," +
$"sentry_client={SdkVersion.Instance.Name}/{SdkVersion.Instance.Version}," +
$"sentry_key={ParsedDsn.PublicKey}" +
(ParsedDsn.SecretKey is { } secretKey ? $",sentry_secret={secretKey}" : null);

return new HttpRequestMessage
{
RequestUri = ParsedDsn.GetEnvelopeEndpointUri(),
Method = HttpMethod.Post,
Headers = { { "X-Sentry-Auth", authHeader } },
Content = content
};
}

/// <summary>
/// Scope state processor.
/// </summary>
Expand Down
Loading