Repository navigation
Polish iPad crash lines and log a failed USB connection once - #133
Merged
Merged
Conversation
Early MetricKit payloads can hold the binary's load address in the text-segment offset, so the offset alone can't place the frame. Each frame is now binary+0x<offset>@0x<address>, and the final scrub keeps the address, which the line formats from a number. The same hex in a binary name is still scrubbed.
64-bit codes such as EXC_GUARD and JETSAM reasons have 16 hex digits with a letter, so the final scrub turned them into code:<id> and the reason the app was killed was lost. The scrub now keeps the code value in the termination field, which is already reduced to namespace and code, and nowhere else.
A .failed connection logged "NWConnection failed" and then fail() logged the same failure again, through the connection that took the link or as the link's own line. A send failure did the same with "NWConnection send". The receive path lost its extra line in #126; the other two now log only through fail(). FramedLink takes its support-log writer as an init parameter so a test can count the lines.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Three small fixes to iPad support-log lines, one commit each.
Each MetricKit frame shows its address (
Core/CrashReporting.swift)Early MetricKit payloads can put the binary's load address in
offsetIntoBinaryTextSegment, and then the offset alone can't place the frame. Each frame inframes=is nowbinary+0x<offset>@0x<address>, using the frame'saddressfrom the call stack tree (0when MetricKit leaves it out, as it does for a missing offset).The final scrub keeps the address: the line formats it from a
UInt64, so it is at most 16 hex digits. The exemption is a lookbehind for+0x<offset>@, which only the frame list produces, because binary names are tokens without@. The same hex in a binary name is still<id>. Eight frames with 64-character names and maximum offsets and addresses stay under 2 KiB.The termination code survives the scrub
64-bit codes such as EXC_GUARD and JETSAM reasons have 16 hex digits with a letter. The scrub turned them into
code:<id>, so the reason the app was killed was lost. The hex scrub now skips the value aftertermination=namespace:<NAMESPACE> code:and nowhere else.termination()has already reduced that value to0xplus at most 16 hex digits, or at most 20 decimal digits. The line has nocode=field (exception_code=is a decimalInt64, which the scrub never matched).Before and after, with synthetic data:
The rest of the line (
MetricKit crash app=0.3.4 build=370 os=ipados:26.1 os_build=23B85 at=2026-10-26T07:33:20Z exception_type=12(EXC_GUARD) exception_code=0 signal=9(SIGKILL) objc_exception=- thread=attributed) is unchanged.A failed USB connection is logged once (
Network/FramedLink.swift)When the connection reported
.failed, FramedLink loggedNWConnection failed: ….fail()then logged the same failure again: through the connection that took the link (state=… USB connection failed: …), or as the link's own line while it waited for its preamble. The send path did the same withNWConnection send: …. #126 removed this extra line from the receive path; the other two now log only throughfail(). The removed lines added nothing, becauselocalizedDescriptionon anNWErroralready carries the errno and its text ("… (Network.NWError error 54 - Connection reset by peer)").In practice the
.failedhandler rarely ran: with a receive outstanding, a reset reaches the receive callback first, and itsfail()clears the state handler. FramedLink now takes its support-log writer as an init parameter (defaultSupportDiagnostics.shared), and the state switch moved intohandle(_:), so a test can drive it.Tests
CrashReportingTests: existing expectations now include each frame's@0x<address>, and a frame without one shows@0x0.testEachFrameShowsItsAddress: a 16-hex-digit address is kept while the same digits in a binary name become<id>. Eight maximum-length frames stay under 2 KiB.testALongTerminationCodeIsKept: a 16-hex-digit GUARD code is kept intermination=, and the same hex as a binary name is still scrubbed. A barecode:<hex>outside the termination field is still scrubbed, and a JETSAM code survives.FramedLinkTests.testAFailedConnectionIsLoggedOnce: a.failedstate gives oneerror [usb] USB connection failed: …line while no connection owns the link. With an owner it gives no line and oneonError, andonClosedfires once either way.scripts/test_ios.sh -only-testing:EternalMonitorTestson an iPad Pro 11-inch (M4) simulator: 349 tests, 0 failures on iOS 26.3 / Xcode 26.3, and 349 tests, 0 failures on iOS 18.6 / Xcode 16.4.session_summarycontract regex (they arecrashevents, not summaries),SupportDiagnostics.redactleaves them unchanged, and they still startMetricKit crash, which the daily check matches.Release notes
iPad crash reports now include more detail to help us find the cause, and a failed USB connection is no longer logged twice.