Appleの公式資料では、Xcodeの「Debug Information Format」に DWARF と DWARF with dSYM File という設定値が用意されています。デバッグ情報生成の公式仕様に照らすと、アドレスだけのクラッシュログを見たときの最短解は、ログのUUIDと完全一致するdSYMを、同じビルドのxcarchiveまたは成果物から回収することです。別のビルドを再コンパイルしても、失われたdSYMの代わりにはなりません。
症状: スタックトレースが関数名ではなく、0x000000010... のようなアドレスで表示される。
最短解法: Binary Images からUUIDとアーキテクチャを取り出し、候補のdSYMを dwarfdump --uuid で照合します。一致しなければ、再ビルドではなく元のアーカイブ、成果物保管庫、またはフレームワーク提供元を探します。
この記事を読むべき人
Xcode OrganizerでTestFlightまたはApp Storeのクラッシュを確認しているのに、スタックがメモリアドレスのまま残る独立開発者向けです。Crashlyticsの「Missing dSYM」に対応したいApp管理者にも使えます。
また、遠隔Macや継続的インテグレーションでビルドし、公開用アーカイブを長期保存しなければならない小規模チームにも適しています。
最初に「ログが壊れた」のか「符号が足りない」のかを分ける
シンボル化前のログでは、アプリ内の関数名、ファイル名、行番号の代わりにロードアドレスが並びます。これは多くの場合、クラッシュレポート自体の破損ではなく、該当するMach-OバイナリとdSYMの組み合わせを解析側が見つけられていない状態です。
まず、ログのBinary Imagesから次の情報を控えます。
- アプリ本体、Extension、動的フレームワークの名前
- 各バイナリのアーキテクチャ
- 各バイナリに記録されたUUID
- アプリのバージョン、ビルド番号、Bundle ID
- どのフレーム内にアドレス表示が残っているか
Appleの不足しているデバッグシンボルを特定する手順でも、クラッシュレポートに示されたUUIDとdSYMのUUID照合が復旧の基準です。したがって、UUIDが一致しない候補は、ファイル名が同じでも採用しません。
dwarfdump --uuid "/path/to/App.app.dSYM"
このコマンドで表示されたUUIDと、ログのBinary ImagesにあるUUIDを比較します。主アプリだけ一致しても、クラッシュしたExtensionや埋め込みフレームワークのUUIDが不一致なら、その部分は完全には読めません。
App Store公開者は元のxcarchiveを基準に復旧する
App StoreやTestFlightに提出したビルドをXcode Organizerで作成していたなら、最初に公開作業を行ったMacのOrganizerとArchivesフォルダーを確認します。一般的な探索対象は次のとおりです。
- Xcode Organizerでバージョン番号とビルド番号が一致するArchiveを探します。
Show in Finder相当の操作で.xcarchiveの実体を開きます。Products/Applications内のアプリ本体と、dSYMs内のdSYMを確認します。- アプリ本体、各Extension、埋め込みフレームワークのUUIDを照合します。
- 見つかったdSYMをXcode Organizerへ読み込ませ、該当ログを再解析します。
Appleのリリース用アプリを配布する公式手順に沿って作成した元Archiveが、もっとも追跡しやすい復旧単位です。App Store Connectのビルド情報とメタデータに関する公式説明を確認しても、現在の通常の公開ビルドについて、元のdSYMを常に再ダウンロードできるとは判断できません。過去のbitcode関連の案内を、すべての現行ビルドに適用しないでください。
xcarchiveを削除した後でも、同じdSYMを作り直せますか。
元のバイナリと同じUUIDを持つdSYMを、別のビルドから再生成することはできません。ソースコード、署名、依存関係、Xcode設定を同じにして再コンパイルしても、旧バイナリと置き換えられる同一の符号ファイルになる保証はないため、Archiveが失われた場合は「旧版の復旧」と「新版以降の保存体制」を分けて判断します。
CrashlyticsのMissing dSYMは3つの層で切り分ける
Crashlyticsで不足UUIDが表示された場合、原因は次の3種類に分かれます。
- ReleaseビルドでdSYMが生成されていない
- 生成済みだが、Crashlyticsのアップロードスクリプトが実行されていない
- アップロード済みだが、対象ビルドまたはUUIDと正しく関連付いていない
Release構成の「Debug Information Format」がDWARF with dSYM Fileになっているかを確認します。設定の意味はAppleのBuild Settingsリファレンスで確認できます。Debug構成だけを直しても、公開用Release ArchiveのdSYM生成には反映されません。
次に、CrashlyticsのRun Script、スクリプト入力ファイル、対象ターゲットを確認します。Firebase公式のiOSクラッシュレポートのシンボル化と不足dSYM対応に沿い、管理画面が示したUUIDのファイルだけをアップロードします。手動処理では、プロジェクトに含まれるupload-symbolsを使い、たとえば次の形で対象プラットフォームとdSYMの場所を明示します。
/path/to/upload-symbols \
-gsp "/path/to/GoogleService-Info.plist" \
-p ios \
"/path/to/App.app.dSYM"
CrashlyticsでMissing dSYMが出たとき、手動アップロードだけで解決しますか。
対象UUIDが一致するdSYMをアップロードすれば、該当ビルドの新しいレポートを読めるようになる可能性があります。ただし、アップロード対象を間違えたり、スクリプト設定が壊れたままだったりすると、次のビルドでも同じ問題が続きます。修正後はテスト用クラッシュを1件発生させ、関数名や行番号まで表示されるか確認してください。
なお、旧ビルドのMissing dSYMは、その旧ビルドに対応した原本が必要です。設定を直して新しいArchiveを作成しても、すでに配布されたバイナリの符号化は補えません。
バイナリの種類ごとに復旧先を変える
1つのアプリでも、主アプリ、Notification ExtensionなどのExtension、動的フレームワークは別々のバイナリとして扱われます。クラッシュの先頭部分だけ読めた状態を「完全復旧」と誤認しないことが重要です。
| 対象バイナリ | 優先する復旧元 | UUID不一致時の判断 |
|---|---|---|
| アプリ本体 | 同じ公開ビルドのxcarchive | 元Archiveまたは保管成果物を探す |
| 自作Extension | 同じArchive、または同一ビルド成果物 | 新しいビルドで代用しない |
| 自作フレームワーク | 同一Archive、成果物リポジトリ | ビルド識別子も併記して照合する |
| プリビルトの第三者フレームワーク | 提供元から該当UUIDのdSYMを取得 | 取得できなければ該当フレームは限定的に解析する |
Xcodeで一致するdSYMを見つけられないときはどうしますか。
まず、ファイル名ではなくUUIDで全候補を検索します。そのうえで主アプリ、Extension、フレームワークを個別に照合し、該当するものだけをXcodeへ読み込ませます。自作フレームワークなら同じArchiveや成果物保管庫から戻し、プリビルトの第三者フレームワークなら、欠落UUIDを添えて提供元へ依頼します。
Appleのクラッシュレポートへ識別可能なシンボル名を追加する仕様も参照し、主アプリのスタックだけでなく、問題のフレームが判読可能になったかを確認します。
注意:Archives、DerivedData、IPAだけを同じものとして扱わないでください。IPAを手元へコピーしても、dSYMやビルド設定、コミット情報まで保存されるとは限りません。削除前に同じ公開ビルドを再解析できることを確認してください。
遠隔Macの公開成果物は「再取得できる単位」で保存する
遠隔MacやCI Runnerで公開ビルドを作る場合、IPAだけをローカルへ転送してホスト側の作業ディレクトリを消す運用は危険です。少なくとも、同じビルド識別子を持つ次の材料を1つの保管単位として扱います。
.xcarchive- アプリ本体、Extension、フレームワークのdSYM
- 書き出したIPAとExportOptions
- Gitコミットまたはソースの識別子
- Xcode、macOS、SDK、依存関係の情報
- 署名に関する参照情報。ただし秘密鍵や認証情報は平文で同梱しない
遠隔Macで作ったdSYMはどこに保存すべきですか。
公開処理が成功した直後に、ビルド番号を含む保管先へ.xcarchiveとdSYMをコピーします。コピー後はファイル一覧、UUID、ハッシュ値、転送結果を記録し、失敗時に通知する仕組みを用意します。キャッシュディレクトリや一時作業フォルダーは、ホスト再起動、セッション切断、Macの交換で消える可能性があるため、長期保管先にはしません。
保管設計では、次の条件を満たすかを確認してください。
- [ ] 公開成功後にArchiveとdSYMの保存処理が自動実行される
- [ ] 主アプリ、Extension、埋め込みフレームワークを個別にUUID照合する
- [ ] IPAだけでなく、xcarchiveとExportOptionsも回収する
- [ ] コピー後にハッシュ値とファイル数を記録する
- [ ] 転送失敗、容量不足、権限エラーを通知できる
- [ ] ホスト再起動後も、ビルド番号から同じ成果物を探せる
- [ ] 保存期間を、アプリのサポート方針、公開中バージョン、バックアップ状態に合わせて決める
- [ ] 削除前に、実際のクラッシュログで再シンボル化を試す
保管期間に全チーム共通の正解はありません。公開中のバージョンが残っているか、旧版の利用者をどこまでサポートするか、別のバックアップが本当に復元できるかを確認してから削除してください。
最後に実バージョンで復旧判定を行う
作業完了の判定は、ファイルが見つかったかどうかではなく、実際の公開バージョンを再解析できるかで行います。次の順番で記録を残すと、担当者が変わっても判断を引き継げます。
- 公開済みクラッシュログからUUIDとアドレスを控えます。
- dSYMのUUIDを
dwarfdump --uuidで照合します。 - Xcode OrganizerへArchiveを読み込ませます。
- Crashlyticsへ不足していたdSYMをアップロードします。
- XcodeとCrashlyticsの両方で、関数名・ファイル名・行番号を確認します。
- 復旧できなかったバージョンと、欠落している第三者フレームワークを記録します。
Appleは、UUIDが一致するバイナリとdSYMを使ってクラッシュログを解析する前提を示しています。詳しい照合方法は不足シンボルの検索に関する公式資料に沿って確認してください。
判断は次の3つに分けます。
- 直ちに復旧: 同じUUIDのdSYMまたはxcarchiveが見つかり、XcodeかCrashlyticsで読みやすいスタックを確認できた。
- 第三者へ依頼: 自作部分は復旧したが、プリビルトフレームワークのUUIDだけが不足している。
- 後続版のみ修正: 元のArchiveがなく、旧バイナリに一致するdSYMを回収できない。以後の自動保存とアップロードを先に直す。
個人PCだけにArchiveが残る運用では、担当者の端末交換、ディスク整理、CIの作業領域削除がそのまま診断不能につながります。現在の方法にも、保存先が分散すること、ホスト停止時に成果物へアクセスできないこと、手動アップロードが担当者依存になること、環境を交換すると同じツールチェーンを再現しにくいことがあります。長期の高負荷処理や物理接続が必要なら自前のMacが適しますが、公開とクラッシュ診断のために常時利用できるMacを一時的または継続的に確保したいなら、KVMFLUXの遠隔Mac利用方法を選択肢にできます。料金や保存条件を確認したうえで、まず実際のArchiveを1件保管・復元できるかを試すなら、KVMFLUXのプラン案内から運用条件を照合してください。