Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
34 changes: 16 additions & 18 deletions integration-test/ios.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ BeforeDiscovery {
$script:simulator = Get-IosSimulatorUdid -PreferredStates @('Booted')
}

Describe 'iOS app (<tfm>, <configuration>)' -ForEach @(
Describe 'iOS app (<tfm>, <configuration>, <runtime>)' -ForEach @(
# Note: we can't run against net10 and net9 becaus .NET 10 requires Xcode 26.2 and .NET 9 requires Xcode 26.0.
# The macOS GitHub Actions runners only have Xcode 26.1+ installed and no support for Xcode 26.2 is planned for
# net9.0-ios: https://github.com/dotnet/macios/issues/24199#issuecomment-3819021247
@{ tfm = "net10.0-ios26.2"; configuration = "Release" }
@{ tfm = "net10.0-ios26.2"; configuration = "Debug" }
#
# TODO: add coreclr when available
@{ tfm = "net10.0-ios26.2"; configuration = "Release"; runtime = "mono" }
@{ tfm = "net10.0-ios26.2"; configuration = "Debug"; runtime = "mono" }
) -Skip:(-not $script:simulator) {
BeforeAll {
. $PSScriptRoot/../scripts/device-test-utils.ps1
Expand All @@ -29,10 +31,12 @@ Describe 'iOS app (<tfm>, <configuration>)' -ForEach @(
$rid = "iossimulator-$arch"

Write-Host "::group::Build Sentry.Maui.Device.IntegrationTestApp.csproj"
$useMonoRuntime = if ($runtime -eq 'mono') { 'true' } else { 'false' }
dotnet build Sentry.Maui.Device.IntegrationTestApp.csproj `
--configuration $configuration `
--framework $tfm `
--runtime $rid
--runtime $rid `
-p:UseMonoRuntime=$useMonoRuntime
| ForEach-Object { Write-Host $_ }
Write-Host '::endgroup::'
$LASTEXITCODE | Should -Be 0
Expand Down Expand Up @@ -90,7 +94,7 @@ Describe 'iOS app (<tfm>, <configuration>)' -ForEach @(
UninstallIosApp
}

It 'captures managed crash (<configuration>)' {
It 'captures managed crash (<configuration>, <runtime>)' {
$result = Invoke-SentryServer {
param([string]$url)
RunIosApp -Dsn $url -TestArg "Managed"
Expand All @@ -99,25 +103,24 @@ Describe 'iOS app (<tfm>, <configuration>)' -ForEach @(

$result.HasErrors() | Should -BeFalse
$result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.ApplicationException`""
# TODO: fix redundant SIGABRT (#3954)
{ $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"SIGABRT`"" } | Should -Throw
{ $result.Envelopes() | Should -HaveCount 1 } | Should -Throw
$result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"(EXC_[A-Z_]+|SIG[A-Z]+)`""
$result.Envelopes() | Should -HaveCount 1
}

It 'captures native crash (<configuration>)' {
It 'captures native crash (<configuration>, <runtime>)' {
$result = Invoke-SentryServer {
param([string]$url)
RunIosApp -Dsn $url -TestArg "Native"
RunIosApp -Dsn $url
}

$result.HasErrors() | Should -BeFalse
$result.Envelopes() | Should -AnyElementMatch "`"type`":`"EXC_[A-Z_]+`""
$result.Envelopes() | Should -AnyElementMatch "`"type`":`"(EXC_[A-Z_]+|SIG[A-Z]+)`""
$result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"System.\w+Exception`""
$result.Envelopes() | Should -HaveCount 1
}

It 'captures null reference exception (<configuration>)' {
It 'captures null reference exception (<configuration>, <runtime>)' {
$result = Invoke-SentryServer {
param([string]$url)
RunIosApp -Dsn $url -TestArg "NullReferenceException"
Expand All @@ -126,12 +129,7 @@ Describe 'iOS app (<tfm>, <configuration>)' -ForEach @(

$result.HasErrors() | Should -BeFalse
$result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.NullReferenceException`""
# TODO: fix redundant EXC_BAD_ACCESS in Release (#3954)
if ($configuration -eq 'Release') {
{ $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"EXC_BAD_ACCESS`"" } | Should -Throw
} else {
$result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"EXC_BAD_ACCESS`""
$result.Envelopes() | Should -HaveCount 1
}
$result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"(EXC_[A-Z_]+|SIG[A-Z]+)`""
$result.Envelopes() | Should -HaveCount 1
}
}
9 changes: 6 additions & 3 deletions scripts/build-sentry-cocoa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,17 @@ xcodebuild archive -project Sentry.xcodeproj \
-sdk "$ios_sdk" \
-archivePath ./Carthage/output-ios.xcarchive \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1'
./scripts/remove-architectures.sh ./Carthage/output-ios.xcarchive arm64e
xcodebuild archive -project Sentry.xcodeproj \
-scheme Sentry \
-configuration Release \
-sdk "$ios_simulator_sdk" \
-archivePath ./Carthage/output-iossimulator.xcarchive \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1'
xcodebuild -create-xcframework \
-framework ./Carthage/output-ios.xcarchive/Products/Library/Frameworks/Sentry.framework \
-framework ./Carthage/output-iossimulator.xcarchive/Products/Library/Frameworks/Sentry.framework \
Expand All @@ -73,7 +75,8 @@ xcodebuild archive -project Sentry.xcodeproj \
-destination 'generic/platform=macOS,variant=Mac Catalyst' \
-archivePath ./Carthage/output-maccatalyst.xcarchive \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1'
./scripts/remove-architectures.sh ./Carthage/output-maccatalyst.xcarchive arm64e
xcodebuild -create-xcframework \
-framework ./Carthage/output-maccatalyst.xcarchive/Products/Library/Frameworks/Sentry.framework \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@

// This is likely a terminal exception so try to send the crash report before shutting down
_hub?.Flush();

// Under Mono, Disable/UnwindNativeCode call mono_raise_exception which can unwind into
// a managed catch and never hit abort(). The thread-local ignore flag would then linger
// and silently swallow an unrelated later SIGABRT on this thread, so skip arming it. See
// https://github.com/dotnet/macios/blob/be8a2ca1057242f745ef58011a02ffe21326d180/runtime/runtime.m#L2215
var isMono = Type.GetType("Mono.Runtime") != null;
if (isMono && e.ExceptionMode is MarshalManagedExceptionMode.Disable
or MarshalManagedExceptionMode.UnwindNativeCode)
{
return;
}

// Otherwise the runtime will call abort() after we return — directly via
// xamarin_assertion_message, or indirectly via the uncaught-NSException handler for
// ThrowObjectiveCException. Tell SentryCrash to ignore that SIGABRT so we don't emit a
// duplicate native crash for an exception we've already captured. See
// https://github.com/dotnet/macios/blob/be8a2ca1057242f745ef58011a02ffe21326d180/runtime/runtime.m#L2285
const int SIGABRT = 6;
SentryCocoaHybridSdk.IgnoreNextSignal(SIGABRT);

Check warning on line 64 in src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs

View check run for this annotation

@sentry/warden / warden: code-review

New signal handling logic lacks test coverage

The new code paths for Mono runtime detection, early return on Disable/UnwindNativeCode modes, and the IgnoreNextSignal call are not covered by tests. The existing test file `RuntimeMarshalManagedExceptionIntegrationTests.cs` only tests basic exception capturing and event handling but doesn't verify the new signal suppression behavior. This is important defensive code that prevents duplicate crash reports and should be verified.
Comment thread
sentry[bot] marked this conversation as resolved.
Outdated
Comment thread
sentry-warden[bot] marked this conversation as resolved.
Outdated
}
}
}
Loading