Skip to content

XCFramework releases ship no dSYMs and are fully stripped — "Upload Symbols Failed" on App Store Connect, parser crashes unsymbolicatable #103

Description

@dubadub

Summary

The CooklangParserFFI.xcframework attached to each release ships without dSYMs, and the binary inside it is fully stripped. Every app that embeds it gets an "Upload Symbols Failed" warning from App Store Connect on upload, and any crash with frames inside the Rust parser is unsymbolicatable in Xcode Organizer.

Observed with cooklang-rs 0.18.7 consumed via SPM.

What App Store Connect reports

Upload Symbols Failed
The archive did not include a dSYM for the CooklangParserFFI.framework with the
UUIDs [AFCB4B3B-C9E0-32A5-8B3D-CF5BC8B75E1E]. Ensure that the archive's dSYM
folder includes a DWARF file for CooklangParserFFI.framework with the expected UUIDs.

Evidence

The archive contains dSYMs for everything built from source, but nothing for CooklangParserFFI:

$ ls CooklangApp.xcarchive/dSYMs
CooklangApp.app.dSYM
Lottie.framework.dSYM
ShareImportExtension.appex.dSYM
WidgetsExtension.appex.dSYM

The framework is embedded as a dynamic library and has no symbol table at all:

$ file CooklangApp.app/Frameworks/CooklangParserFFI.framework/CooklangParserFFI
Mach-O 64-bit dynamically linked shared library arm64

$ nm -a CooklangApp.app/Frameworks/CooklangParserFFI.framework/CooklangParserFFI
no symbols

Cause

Two independent things:

  1. [profile.release] in the root Cargo.toml sets strip = true, so the release build carries no debug info and no symbol table. There is nothing for dsymutil to work from. (This is the same setting already flagged in Bug: UniFFI bindings generation broken since v0.17.5 due to strip = true #85 for breaking uniffi-bindgen.)

  2. .github/workflows/release.yml calls xcodebuild -create-xcframework without -debug-symbols, so even if dSYMs were produced they would not be packaged into the xcframework — and consumers would still have nothing for Xcode to copy into their archive.

Suggested fix

Keep debug info for the Apple targets via a dedicated profile, so the existing release behaviour is untouched:

[profile.release-apple]
inherits = "release"
strip = "none"
debug = 1

Then, per slice, split the debug map out and strip the shipped binary so framework size stays roughly where it is today:

dsymutil "$FRAMEWORK/$FRAMEWORK_LIBRARY_NAME" -o "$FRAMEWORK.dSYM"
strip -x "$FRAMEWORK/$FRAMEWORK_LIBRARY_NAME"

And pass the dSYMs when assembling the xcframework (-debug-symbols requires absolute paths):

xcodebuild -create-xcframework \
    -framework     "$OUT/frameworks/ios/$FRAMEWORK_NAME" \
    -debug-symbols "$PWD/$OUT/frameworks/ios/$FRAMEWORK_NAME.dSYM" \
    -framework     "$OUT/frameworks/sim/$FRAMEWORK_NAME" \
    -debug-symbols "$PWD/$OUT/frameworks/sim/$FRAMEWORK_NAME.dSYM" \
    -framework     "$OUT/frameworks/macos/$FRAMEWORK_NAME" \
    -debug-symbols "$PWD/$OUT/frameworks/macos/$FRAMEWORK_NAME.dSYM" \
    -output "$OUT/$XC_FRAMEWORK_NAME"

Xcode picks the dSYMs up from the xcframework and copies them into the consuming app's archive automatically, which clears the warning.

Impact

Not a submission blocker — the upload itself still succeeds. But it means production crashes inside the parser come back as raw addresses, so parser-level crashes can't be diagnosed from App Store Connect or Sentry.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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