診断ファイル(*.diag
)があるときに、リリース済みのアプリの場合、診断ファイル内のコールスタックにはアドレスしか書かれておらず、どこの処理なのかがわからないことがあります。このようなときはdSYMを使って、アドレスからシンボル名を調べて解析します。
この記事では、dSYMを使って、アドレスからシンボル名を調べる方法について解説します。
診断ファイルの構造
診断ファイルは以下のような構造になっています。
- 日時
- 環境情報(OSバージョンとCPUアーキテクチャ)
- 診断対象アプリやプロセスの情報
- イベントの種類
- ハードウェアの情報
- 言語設定
- イベント発生原因となった処理のスタックトレース
- 全スレッドのスタックトレース
- バイナリのロード先アドレス
dSYMが使用可能か調べる
出力されるアドレスと、dSYMに記録されているアドレスがマッチするかを確認します。まず、dSYMのUUIDを取得します。
dwarfdump --uuid /path/to/YourApp.app.dSYM
たとえば、次のように出力されます。
UUID: C4C2CCCC-AAAA-32DA-8D93-A21490FDB7DA (x86_64) YourApp.app.dSYM/Contents/Resources/DWARF/YourApp
UUID: 1234A442-4A8B-BABA-9A67-507099DEE4B0 (arm64) YourApp.app.dSYM/Contents/Resources/DWARF/YourApp
診断ファイルの全スタックトレースの直前、以下のところにUUIDが出力されています。
Powerstats for: YourApp [3552]
UUID: 1234A442-4A8B-BABA-9A67-507099DEE4B0
Path: /Applications/YourApp.app/Contents/MacOS/YourApp
Architecture: arm64
Architecture
にarm64
と出力されているため、arm64
版のUUIDを比較します。一致しているので、このdSYMが使用できます。
dSYMからシンボル名を調べる
dSYMからシンボル名を取得するには、atos
を使用します。
atos -o /path/to/YourApp.app.dSYM/Contents/Resources/DWARF/YourApp -arch architecture -l ロードアドレス シンボルアドレス
成功すると、以下のようにシンボル名が出力されます。
-[YourApp foo] (in YourApp) (YourApp.mm:0)
シンボルアドレス
シンボル情報をdSYMに出力している場合、アプリ内にはシンボル情報がないため、スタックトレースには以下のように出力されています。
??? (バイナリファイル名 + 10進数の相対アドレス) [16進数のシンボルアドレス]
atos
に指定するシンボルアドレスは、上記の「16進数のシンボルアドレス」を使用します。
ロードアドレス
バイナリのロードアドレスは、全スレッドのスタックトレースの後ろに出力されています。
Binary Images:
0x100704000 - 0x100ba7fff com.example.YourApp 1.0 (1.0) <1234A442-4A8B-BABA-9A67-507099DEE4B0> /Applications/YourApp.app/Contents/MacOS/YourApp
この例では、0x100704000
がロードアドレスです。