Skip to content

EmbraceIO v6 crashes on Xcode 26 simulator (MetricKit mxSignpost missing) #561

Description

@roc
Field Details
Environment Embrace iOS SDK v6.6.0, Xcode 26.0, iOS 26 simulator, React Native 0.83.4
Crash Segfault in EmbraceMetricKitSpan.init(name:signpostId:) at MetricKitSpan.swift:56mxSignpost resolves to nil on simulator.
Root cause #if canImport(MetricKit) passes on simulator (framework exists) but mxSignpost isn’t exported from the simulator variant. The nil function pointer causes the segfault.
Suggested fix Runtime nil-check on mxSignpost before calling, or #if !targetEnvironment(simulator) guard around MetricKit usage.
Workaround Patching EmbraceManager.swift to skip Embrace.setup() on simulator with #if targetEnvironment(simulator).

More deets:

Environment

  • Embrace iOS SDK: 6.6.0 (latest, via @embrace-io/react-native 6.6.0)
  • Xcode: 26.0 (26A5082a) — macOS 26.4 (25E246)
  • Simulator: iPhone 16 Pro, iOS 26.0, arm64
  • React Native: 0.83.4, Expo SDK 55
  • Also affects Release simulator builds (not just Debug)

Crash report

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000

Thread 0 Crashed :: Dispatch queue: com.apple.main-thread
0 ??? 0x0 ???
1 MyApp EmbraceMetricKitSpan.init(name:signpostId:) + 508 (MetricKitSpan.swift:56)
2 MyApp static EmbraceMetricKitSpan.begin(name:force:) + 128 (MetricKitSpan.swift:24)
3 MyApp specialized static Embrace.setup(options:otelResource:) + 592 (Embrace.swift:135)
4 MyApp closure #1 in EmbraceManager.startNativeEmbraceSDK (EmbraceManager.swift:68)

Root cause

MetricKitSpan.swift guards with #if canImport(MetricKit) && os(iOS), which passes on simulator
because the MetricKit framework exists. But the Xcode 26 simulator variant of MetricKit does not export
the mxSignpost function. The symbol links at compile time (it's in the header) but resolves to a nil
function pointer at runtime, causing the segfault when called at line 56.

This affects both the AppDelegate path (EmbraceInitializer.start()) and the React Native module path
(EmbraceManager.startNativeEmbraceSDK), since both call Embrace.setup() which immediately creates an
EmbraceMetricKitSpan.

Adding -weak_framework MetricKit to linker flags avoids the earlier dyld symbol-not-found crash but
doesn't prevent the runtime segfault — the weak-linked symbol is nil and the code calls it
unconditionally.

Additional issue

EmbraceIO/run.sh (referenced by the Expo config plugin's upload build phase) is not included in the
EmbraceIO v6 pod, causing a separate build failure:

line 2: ${PODS_ROOT}/EmbraceIO/run.sh: No such file or directory

Suggested fixes

  1. Guard mxSignpost calls with a runtime nil-check or #if !targetEnvironment(simulator)
  2. Ship run.sh in the EmbraceIO pod, or don't add the upload build phase if the script won't be
    present

Our workaround

Post-prebuild script that:

  • Patches EmbraceManager.swift to resolve(false) on simulator via #if targetEnvironment(simulator)
  • Patches EmbraceInitializer.swift to skip import EmbraceIO and Embrace.setup() on simulator
  • Adds -weak_framework MetricKit to linker flags
  • Guards the upload build phase with a file-existence check

This means Embrace telemetry is completely disabled on simulator, which blocks local QA workflows.

Reproduction

  1. Create an Expo or React Native app with @embrace-io/react-native 6.6.0
  2. Configure the Embrace Expo config plugin with a valid iOSAppId and apiToken
  3. npx expo prebuild --platform ios
  4. Build for iOS simulator with Xcode 26 (-sdk iphonesimulator)
  5. Launch — crashes immediately on Embrace.setup()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions