[SDTEST-2842] Migrate from PLCrashReporter to KSCrash#245
Merged
Conversation
PLCrashReporter (microsoft/plcrashreporter) was archived and is no
longer maintained. Replace it with KSCrash 2.5.1 (kstenerud/KSCrash,
MIT) — actively maintained, used by Sentry/Bugsnag/Crashlytics, and
covers the same crash types plus C++ exceptions and main-thread
deadlocks.
Behavior changes:
- DD_DISABLE_MACH_CRASH_HANDLER now controls Mach exception monitoring
uniformly across iOS, macOS, and tvOS. tvOS is silently BSD-only at
the KSCrash level (KSCRASH_HAS_MACH=0), so the flag is a no-op there.
- Per-test span context flows through KSCrash.userInfo (base64-encoded
SimpleSpanData) instead of the PLCrashReporter customData blob.
- Crash log text format is reproduced from KSCrash JSON via a small
CrashLog model layer; downstream consumers see equivalent output.
Refactors:
- New Crashes/CrashLog.swift introduces structured CrashLog/Header/
Thread/Frame/BinaryImage value types. KSCrash JSON parses once into
the model; symbolication mutates frames in place; render() produces
the human-readable text only at the end.
- DDSymbolicator.symbolicate now takes inout CrashLog. Frames are
grouped by (binary, library load address) so each unique binary is
opened by atos exactly once instead of one spawn per frame —
measured 82s → ~6s on the macOS smoke test.
- Removed dead methods from DDSymbolicator: address(forSymbolName:),
symbolWithAtos, swiftTestMangledName + helpers, plus 17 test cases
that only exercised the dead mangler.
- Drops the crashLineRegex round-trip; symbolication operates on
UInt64 addresses directly, fixing a latent dladdr-fallback bug
where Float64("0x...") always returned nil.
Verified: macOS XCTest, iOS Simulator XCTest, tvOS Simulator XCTest,
macOS Swift Testing — all four crash integration tests green.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
KSCrash 2.4.0 deprecated the block-based `crashNotifyCallback` in favor of `isWritingReportCallback`, a `@convention(c)` function pointer that takes an `ExceptionHandlingPlan` argument so callers can react to the async-safety constraints of the crash-time context. Lift the callback body to a file-scope `@convention(c)` constant — the new API can't capture locals. State is reached via the file-private static properties on `DDCrashes`, which are non-capturing references at file scope. Plan/writer pointers are unused. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Mirror the failed-test span's `error.*` and `error.crash_log.NN` values onto the runner test as `returned_*` tags, so the captured crash log content is visible in the Datadog UI when reviewing the integration test run. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
anmarchenko
approved these changes
May 8, 2026
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.
Summary
microsoft/[email protected]with actively-maintainedkstenerud/[email protected](MIT). Same XCFramework distribution model — KSCrash links statically intoDatadogSDKTesting.xcframework, no consumer-facing dependency change.CrashLogmodel layer (Sources/DatadogSDKTesting/Crashes/CrashLog.swift) so the KSCrash JSON dictionary parses once into structured frames; symbolication mutates frames in place;render()produces the human-readable text only at the end. Eliminates the prior text → regex → text round-trip.DDSymbolicator.symbolicate(_:): frames are grouped by(binary, library load address)so each unique binary is opened byatosexactly once. Measured 82s → ~6s on the macOS crash smoke test (12× speedup) with byte-identical symbolicated output.address(forSymbolName:library:),symbolWithAtos,swiftTestMangledName+mangleIdentifier/upperCase, plus the 17 test cases that only exercised the dead mangler. Dropinternal import CodeCoverage(no longer used).DD_DISABLE_MACH_CRASH_HANDLERnow applies uniformly across iOS, macOS, and tvOS. KSCrash itself disables Mach on tvOS (KSCRASH_HAS_MACH=0), so the flag is a no-op there and the runtime falls back to BSD signal handlers.Test plan
xcodebuild buildpasses for macOS, iOS Simulator, tvOS Simulator.IntegrationTests/UnitTestsXCTestSmoke/crash()— green.IntegrationTests/UnitTestsSwiftTestingSmoke/crash()— green.success == falseon crashed run,spans.count == 2, error fields populated for failed test, span identity (test/suite/module/session) reconstructed fromKSCrash.userInfo.tests/integrationmatrix in CI before merging.🤖 Generated with Claude Code