Repository navigation
Conversation
148f2ef to
00c47ba
Compare
468e51e to
b42ea3f
Compare
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
Raise the range floor from `^57.0.0` to `^57.0.26` (the latest 57.x patch) and advance the lockfile accordingly. 57.0.26 is the first SDK 57 release bundled in the sample that ships Expo's `ExpoAppSceneDelegate`, so the floor now reflects the real minimum while keeping the caret for future 57.x patches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reproduces getsentry/sentry-cocoa#9281 in the Expo sample and asserts the crash-time screenshot path does not hang the crash handler: - `samples/expo/plugins/withIosSceneLifecycle.js` makes the sample adopt the iOS UIScene lifecycle with Expo's `EXExpoAppSceneDelegate` (a Swift, MainActor-isolated `UIWindowSceneDelegate`) and injects an off-main `abort()` test hook gated by `SENTRY_TEST_ABORT=1`. - `scripts/verify-ios-crash-screenshot-no-freeze.sh` builds the sample, crashes it off the main thread, and asserts a clean terminate + captured screenshot with no `dispatch_assert_queue_fail` re-entry. - `.github/workflows/ios-crash-screenshot-no-freeze.yml` runs it on a bundled cocoa version bump and on manual dispatch. This check is RED until the bundled sentry-cocoa carries the #9281 fix; the cocoa-bump PR turns it green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
00c47ba to
5182390
Compare
b42ea3f to
5f49f59
Compare
…shot-freeze-check
antonis
left a comment
There was a problem hiding this comment.
Marking as blocked on a new Cocoa version that includes a fix for getsentry/sentry-cocoa#9281
Android (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3a829f0+dirty | 474.65 ms | 518.24 ms | 43.59 ms |
| 4953e94+dirty | 442.02 ms | 456.52 ms | 14.50 ms |
| 3e3142c+dirty | 441.26 ms | 496.06 ms | 54.80 ms |
| 7ff4d0f+dirty | 413.81 ms | 450.64 ms | 36.83 ms |
| 7ac3378+dirty | 404.78 ms | 439.84 ms | 35.06 ms |
| 083e3ef+dirty | 446.67 ms | 491.68 ms | 45.01 ms |
| a858ac3+dirty | 426.50 ms | 484.82 ms | 58.32 ms |
| 44c8b3f+dirty | 414.20 ms | 457.28 ms | 43.08 ms |
| 61cc206+dirty | 522.33 ms | 553.98 ms | 31.65 ms |
| 5a010b7+dirty | 425.62 ms | 469.38 ms | 43.76 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3a829f0+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| 4953e94+dirty | 43.75 MiB | 48.08 MiB | 4.33 MiB |
| 3e3142c+dirty | 49.74 MiB | 55.44 MiB | 5.70 MiB |
| 7ff4d0f+dirty | 48.30 MiB | 53.60 MiB | 5.30 MiB |
| 7ac3378+dirty | 43.75 MiB | 48.13 MiB | 4.37 MiB |
| 083e3ef+dirty | 49.74 MiB | 55.36 MiB | 5.61 MiB |
| a858ac3+dirty | 49.74 MiB | 55.08 MiB | 5.34 MiB |
| 44c8b3f+dirty | 48.30 MiB | 53.46 MiB | 5.15 MiB |
| 61cc206+dirty | 49.74 MiB | 55.36 MiB | 5.62 MiB |
| 5a010b7+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
iOS (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3d31fcf+dirty | 3838.09 ms | 1223.46 ms | -2614.63 ms |
| 0b5120f+dirty | 3838.39 ms | 1232.91 ms | -2605.48 ms |
| f9c1ed4+dirty | 3833.98 ms | 1226.30 ms | -2607.68 ms |
| a5d243c+dirty | 3842.35 ms | 1214.29 ms | -2628.06 ms |
| 3817909+dirty | 1183.90 ms | 1187.50 ms | 3.60 ms |
| 6176a94+dirty | 3836.50 ms | 1217.64 ms | -2618.86 ms |
| d7d54c6+dirty | 3827.13 ms | 1217.18 ms | -2609.95 ms |
| 68672fc+dirty | 3841.58 ms | 1228.89 ms | -2612.69 ms |
| 244f6e8+dirty | 3833.36 ms | 1212.96 ms | -2620.41 ms |
| 0d58e97+dirty | 3850.70 ms | 1228.77 ms | -2621.92 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3d31fcf+dirty | 4.98 MiB | 6.56 MiB | 1.58 MiB |
| 0b5120f+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| f9c1ed4+dirty | 4.98 MiB | 6.50 MiB | 1.53 MiB |
| a5d243c+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| 3817909+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 6176a94+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| d7d54c6+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 68672fc+dirty | 5.15 MiB | 6.71 MiB | 1.55 MiB |
| 244f6e8+dirty | 4.98 MiB | 6.56 MiB | 1.58 MiB |
| 0d58e97+dirty | 5.15 MiB | 6.93 MiB | 1.78 MiB |
iOS (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 038a6d7+dirty | 3838.96 ms | 1218.86 ms | -2620.10 ms |
| 41d6254+dirty | 3849.78 ms | 1233.91 ms | -2615.86 ms |
| 20fbd51+dirty | 3832.52 ms | 1206.13 ms | -2626.39 ms |
| 5748023+dirty | 3844.74 ms | 1225.49 ms | -2619.26 ms |
| 3b6e9f9+dirty | 3822.77 ms | 1208.00 ms | -2614.77 ms |
| 71abba0+dirty | 3852.70 ms | 1224.53 ms | -2628.16 ms |
| 40c9884+dirty | 3826.11 ms | 1217.04 ms | -2609.07 ms |
| 2cac31b+dirty | 3854.43 ms | 1212.35 ms | -2642.08 ms |
| 1d3572b+dirty | 3830.71 ms | 1222.23 ms | -2608.49 ms |
| 5ee78d6+dirty | 3815.71 ms | 1217.04 ms | -2598.67 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 038a6d7+dirty | 5.15 MiB | 6.70 MiB | 1.55 MiB |
| 41d6254+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
| 20fbd51+dirty | 4.98 MiB | 6.46 MiB | 1.49 MiB |
| 5748023+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| 3b6e9f9+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| 71abba0+dirty | 5.15 MiB | 6.67 MiB | 1.52 MiB |
| 40c9884+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 2cac31b+dirty | 4.98 MiB | 6.55 MiB | 1.58 MiB |
| 1d3572b+dirty | 4.98 MiB | 6.56 MiB | 1.58 MiB |
| 5ee78d6+dirty | 5.15 MiB | 6.69 MiB | 1.53 MiB |
Android (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| b0d3373+dirty | 412.17 ms | 452.84 ms | 40.67 ms |
| b9bebee+dirty | 500.50 ms | 536.42 ms | 35.92 ms |
| a0a3177+dirty | 427.85 ms | 473.94 ms | 46.09 ms |
| 580fb5c+dirty | 515.72 ms | 585.38 ms | 69.66 ms |
| 9ad4522+dirty | 432.43 ms | 450.91 ms | 18.49 ms |
| a9df5ce+dirty | 430.04 ms | 487.45 ms | 57.41 ms |
| bbb8d67+dirty | 465.41 ms | 502.40 ms | 36.99 ms |
| d61b289+dirty | 548.04 ms | 602.98 ms | 54.94 ms |
| 4966363+dirty | 415.67 ms | 448.60 ms | 32.93 ms |
| 3d31fcf+dirty | 519.98 ms | 549.61 ms | 29.63 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| b0d3373+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| b9bebee+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| a0a3177+dirty | 49.74 MiB | 55.37 MiB | 5.63 MiB |
| 580fb5c+dirty | 49.74 MiB | 54.79 MiB | 5.05 MiB |
| 9ad4522+dirty | 49.74 MiB | 55.38 MiB | 5.63 MiB |
| a9df5ce+dirty | 49.74 MiB | 55.36 MiB | 5.62 MiB |
| bbb8d67+dirty | 49.74 MiB | 55.36 MiB | 5.62 MiB |
| d61b289+dirty | 50.56 MiB | 56.62 MiB | 6.06 MiB |
| 4966363+dirty | 48.30 MiB | 53.54 MiB | 5.24 MiB |
| 3d31fcf+dirty | 49.74 MiB | 55.38 MiB | 5.63 MiB |
| # It validates whatever sentry-cocoa the SDK currently bundles, so it is wired to run when the | ||
| # bundled cocoa version changes (the podspec / version table) and on manual dispatch. It will be | ||
| # RED until the bundled cocoa is bumped to a release containing the fix — that is the point: the | ||
| # cocoa-bump PR turns it green. | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - "packages/core/RNSentry.podspec" | ||
| - "packages/core/scripts/sentry_utils.rb" | ||
| - ".github/workflows/ios-crash-screenshot-no-freeze.yml" | ||
| - "scripts/verify-ios-crash-screenshot-no-freeze.sh" | ||
| - "samples/expo/plugins/withIosSceneLifecycle.js" | ||
| pull_request: | ||
| paths: | ||
| - "packages/core/RNSentry.podspec" | ||
| - "packages/core/scripts/sentry_utils.rb" | ||
| - ".github/workflows/ios-crash-screenshot-no-freeze.yml" | ||
| - "scripts/verify-ios-crash-screenshot-no-freeze.sh" | ||
| - "samples/expo/plugins/withIosSceneLifecycle.js" |
There was a problem hiding this comment.
The known-red workflow makes pre-fix Cocoa bumps fail CI
The workflow runs on PRs changing the Cocoa version files and on changes to the new regression-check files, but has no version gate or allow-failure setting. As documented, it fails until the bundled sentry-cocoa contains the #9281 fix, so this PR and pre-fix Cocoa bump PRs report a failing check; if that check is required, they cannot merge without bypassing it. Gate the job on a fixed version, allow failure until then, or land it together with the fixing bump.
Evidence
- The PR path filters include
packages/core/RNSentry.podspec,packages/core/scripts/sentry_utils.rb, the workflow, and the verification script, so changes to those files start this job. - The workflow comments explicitly say the job will be red until a Cocoa release containing #9281 is bundled;
RNSentry.podspeccurrently pins9.30.1. - The job runs
scripts/verify-ios-crash-screenshot-no-freeze.shunconditionally, with no version condition orcontinue-on-error; the script exits nonzero when the freeze is present.
Identified by Warden · code-review · A3X-54G
| TERMINATED=0 | ||
| for _ in $(seq 1 $((8 + ABORT_DELAY_PADDING))); do | ||
| sleep 1 | ||
| ps -p "$PID" >/dev/null 2>&1 || { TERMINATED=1; break; } | ||
| done | ||
|
|
||
| if [ "$TERMINATED" -eq 0 ]; then | ||
| echo "Process $PID still alive long after the abort — capturing the hung stack:" | ||
| sample "$PID" 2 -file "$WORKDIR/sample.txt" 2>/dev/null || true | ||
| grep -iE "dispatch_assert_queue|isCurrentExecutor|collectWindowsOnCurrentThread|saveScreenShots|window.getter" \ | ||
| "$WORKDIR/sample.txt" | sort -u | head | ||
| xcrun simctl terminate "$SIM_ID" "$BUNDLE_ID" 2>/dev/null || true | ||
| fail "App FROZE during crash handling — the bundled sentry-cocoa still has issue #9281." | ||
| fi | ||
| echo "Process terminated cleanly after the crash." | ||
|
|
||
| # ---- 6. Assert the crash report + screenshot were produced, with no trap re-entry ---------------- | ||
| log "Validating crash artifacts" | ||
| DATA="$(xcrun simctl get_app_container "$SIM_ID" "$BUNDLE_ID" data)" | ||
| REPORTS="$DATA/Library/Caches/SentryCrash/sentryreactnativeexposample/Reports" | ||
| REPORT="$(ls "$REPORTS"/*.json 2>/dev/null | head -1 || true)" | ||
| SHOT="$(find "$REPORTS" -name 'screenshot.png' 2>/dev/null | head -1 || true)" | ||
|
|
||
| [ -n "$REPORT" ] || fail "No crash report was written." | ||
| [ -n "$SHOT" ] && [ -s "$SHOT" ] || fail "No (non-empty) crash-time screenshot was captured." | ||
| file "$SHOT" | grep -q "PNG image data" || fail "Screenshot is not a valid PNG." | ||
| if grep -q "dispatch_assert_queue_fail" "$REPORT"; then | ||
| fail "Crash report contains a dispatch_assert_queue_fail re-entry — the trap still fires." |
There was a problem hiding this comment.
Regression check can pass without exercising the off-main abort path
Require the process to stay alive until ~8s and assert the crash report is the scheduled background abort (and/or that AppDelegate contains the SENTRY_TEST_ABORT hook); any early main-thread crash with a screenshot can false-pass today.
Evidence
- The poll loop only sets
TERMINATED=1whenps -p "$PID"fails; it never records how long the process lived or that it survived until the scheduled abort. - Setup guards check the scene manifest and
ExpoReactNativeFactoryProvider, but never grep AppDelegate forSENTRY_TEST_ABORT. - Pass criteria are only: process gone, non-empty
screenshot.png, crash JSON present, and nodispatch_assert_queue_fail— no SIGABRT/off-main/thread assertions. - An early main-thread crash (e.g. scene-delegate wiring failure) that still writes a report + screenshot satisfies every check without hitting the off-main screenshot path from cocoa#9281.
Identified by Warden · code-review · SV7-G74
📢 Type of change
📜 Description
Adds a CI regression check that reproduces the sentry-cocoa crash-handler freeze from getsentry/sentry-cocoa#9281 in the Expo sample and asserts the crash-time screenshot path does not hang the crash handler.
💡 Motivation and Context
Guards against regressions of the crash-handler freeze and validates the sentry-cocoa fix once it is bundled into the SDK. Fixes/tracks getsentry/sentry-cocoa#9281 from the React Native side.
💚 How did you test it?
📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps