Skip to content

[SDTEST-2842] Migrate from PLCrashReporter to KSCrash#245

Merged
ypopovych merged 4 commits into
mainfrom
sdtest-2842-migrate-to-kscrash
May 8, 2026
Merged

[SDTEST-2842] Migrate from PLCrashReporter to KSCrash#245
ypopovych merged 4 commits into
mainfrom
sdtest-2842-migrate-to-kscrash

Conversation

@ypopovych

@ypopovych ypopovych commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace archived microsoft/[email protected] with actively-maintained kstenerud/[email protected] (MIT). Same XCFramework distribution model — KSCrash links statically into DatadogSDKTesting.xcframework, no consumer-facing dependency change.
  • Introduce a CrashLog model 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.
  • Optimize DDSymbolicator.symbolicate(_:): frames are grouped by (binary, library load address) so each unique binary is opened by atos exactly once. Measured 82s → ~6s on the macOS crash smoke test (12× speedup) with byte-identical symbolicated output.
  • Remove dead code: address(forSymbolName:library:), symbolWithAtos, swiftTestMangledName + mangleIdentifier/upperCase, plus the 17 test cases that only exercised the dead mangler. Drop internal import CodeCoverage (no longer used).
  • DD_DISABLE_MACH_CRASH_HANDLER now 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 build passes for macOS, iOS Simulator, tvOS Simulator.
  • macOS XCTest crash integration: IntegrationTests/UnitTestsXCTestSmoke/crash() — green.
  • iOS Simulator (iPhone 17) XCTest crash integration — green.
  • tvOS Simulator (Apple TV) XCTest crash integration — green.
  • macOS Swift Testing crash variant: IntegrationTests/UnitTestsSwiftTestingSmoke/crash() — green.
  • All assertions verified: success == false on crashed run, spans.count == 2, error fields populated for failed test, span identity (test/suite/module/session) reconstructed from KSCrash.userInfo.
  • Full tests/integration matrix in CI before merging.
  • Manual sanity check of a crash report rendering in a backend test environment.

🤖 Generated with Claude Code

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]>
@ypopovych
ypopovych requested review from a team as code owners May 8, 2026 12:36
ypopovych and others added 3 commits May 8, 2026 13:38
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]>
@ypopovych
ypopovych requested a review from anmarchenko May 8, 2026 14:12
@ypopovych
ypopovych merged commit 6ebe133 into main May 8, 2026
19 of 25 checks passed
@ypopovych
ypopovych deleted the sdtest-2842-migrate-to-kscrash branch May 8, 2026 14:20
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.

2 participants