Skip to content

feat(devices): catch app crashes on physical iPhones - #21

Draft
lauridskern wants to merge 2 commits into
cindara/capture-crashes-in-chatfrom
cindara/physical-ios-crashes
Draft

lauridskern wants to merge 2 commits into
cindara/capture-crashes-in-chatfrom
cindara/physical-ios-crashes

Conversation

@lauridskern

Copy link
Copy Markdown
Collaborator

Stacked on #20. Merge that first; this PR's base is its branch.

What

The crash toast now works on a connected physical iPhone, for debug and release builds alike. Before this, physical iPhones were skipped because their crash reports stay on the phone.

  • Instant toast. A second relay stream from the bundled log reader, filtered to SpringBoard, catches the crash-signal exit line, which is parsed by the same parseIosAppExit as on simulators. The app's executable name comes from a devicectl device info apps cache that is loaded once per watch and reloaded when an unknown app crashes.
  • Full report. A new one-shot --crash-reports <since-unix-ms> mode in mobile-dev-ios-logs triggers com.apple.crashreportmover, then copies new top-level .ips reports over AFC from com.apple.crashreportcopymobile. The server polls it every 3 s for up to 2 min and picks the report that matches the exit's PID and bundle ID. Nothing is deleted from the phone. Reports over 8 MiB are skipped.
  • parseIosCrashReport now takes an optional simulator ID, so phone reports parse without the CoreSimulator path check.
  • Log sessions on a physical iPhone now run the crash watcher as well, scoped to their process or PID like on simulators.
  • The UI keeps the "fetching stack" state for up to 120 s (was 60 s) to match the server's report deadline.

Telemetry

  • iOS logs.crash.* metrics now carry device_kind (simulator or physical).
  • New logs.crash.report_wait gauge: how long a phone's report took to become readable after its exit was seen.
  • Report mode records no native timing, so the reader's connect timing keeps its meaning (log streaming became ready).
  • Documented in docs/telemetry.md.

Native rebuild

npm run rebuild:ios-logs rebuilt the reader and its bundled dylibs. Homebrew's OpenSSL moved from 3.6.2 to 3.6.3 since the last build, so the bundled libssl/libcrypto and the license text changed accordingly. Matching symbols are in .sentry/native.

Verification

  • npm test: 730 tests, 729 pass, 1 skipped. New tests cover the physical watcher (instant exit, then the matching report after a non-matching one), parsing phone reports, the report-mode helper invocation, the devicectl app-name lookup, the UI watching connected iPhones and not disconnected ones, and the crash metrics with opt-out.
  • npm run package and check:mcp-budget pass; the budget is unchanged.
  • Not yet verified on a real iPhone. The test phone was paired in devicectl, but libimobiledevice couldn't reach it over USB or Wi-Fi during this work. Two things still need a real crash to confirm: that the phone's SpringBoard prints the same Process exited … domain:signal line as the simulator, and how long the phone takes to write the .ips.

Release builds

Release builds behave the same as debug. Exit detection and reports come from iOS, not the app. App frames in a release report are addresses until symbolicated with the build's dSYM, which this PR doesn't do.

Watch SpringBoard's exit lines through a second relay stream for an
instant crash toast, then copy the matching .ips report off the phone
with a new --crash-reports mode in the bundled log reader.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant