dotnet / dotnet/xharness

Apple crash-report fallback can upload a stale unrelated .ips report

Open
#1,672 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
189
Forks
67
Avg merge
1d 12h
Merged PRs (30d)
29

Description

### Description

When copying Apple test results from a device fails, `ResultFileHandler.CopyCrashReportAsync` can upload an old crash report from an unrelated test application.

The current filtering predicate is effectively unbounded:

```csharp
crash.Contains(appInformation.AppName, StringComparison.OrdinalIgnoreCase) ||
crash.EndsWith(".ips", StringComparison.OrdinalIgnoreCase)
```

Because every Apple incident report ends in `.ips`, every report is treated as app-related. The method then selects `.Last()`, which is not sufficient to establish that the report belongs to the current test run.

### Observed failure

In [runtime-extra-platforms build 1551332](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1551332), a tvOS `System.Net.Security.Unit.Tests` run crashed. The immediate result-copy fallback uploaded an older `System.Security.Cryptography.Pkcs.Tests.cpu_resource-2026-08-10-174849.ips` report already present on the device. The current crash occurred on August 12 and belonged to `System.Net.Security.Unit.Tests`.

The later `CrashSnapshotReporter` path correctly found the new report by comparing pre-launch and post-run snapshots after allowing time for report publication.

Affected XHarness package:

`11.0.0-prerelease.26368.1+acc639bea6c5720abf118b8808e18f9cabe90568`

The same filename predicate remains on `main` as of `f10844a1593bd12a5b59046798831ead3eeef2e0`.

### Expected behavior

Only crash reports created during the current application launch should be collected. Collection should allow bounded time for a new report to appear.

Matching only `AppName` is not a complete replacement because report filenames may use `CFBundleExecutable`, Jetsam reports use `JetsamEvent`, and extensions or child processes can use different executable names.

### Suggested direction

Reuse the existing `CrashSnapshotReporter` lifecycle:

1. Snapshot reports before launch.
2. After execution, wait for publication and compute the set difference.
3. Download only newly created reports.
4. Remove or consolidate the immediate filename-based duplicate collection path.

Suggested regression coverage:

- A stale unrelated `.ips` report present before and after the run is not downloaded.
- A delayed new report is downloaded.
- A new `JetsamEvent` or executable-named report is not rejected due to an `AppName` mismatch.

> [!NOTE]
> This issue was drafted with GitHub Copilot.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at ResultFileHandler.CopyCrashReportAsync and trace the existing CrashSnapshotReporter lifecycle, including its pre-launch and post-run snapshots and report-publication wait. Reproduce or add coverage for a stale pre-existing .ips report, a delayed new report, and a new JetsamEvent or executable-named report. Done means only reports created during the current launch are downloaded, without duplicate immediate filename-based collection.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
mobile-dev, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.