Xcode:クラッシュスタックの符号化、クラッシュの位置決め


まず、常識「脳補」を行います.
1.記号表は何ですか.
シンボルテーブルとは、Xcodeプロジェクトのコンパイル後にコンパイル生成されたバイナリファイルのことである.appの同級ディレクトリの下で生成する同名の.dSYMファイル.
.dSYMファイルは実は1つのディレクトリで、サブディレクトリに16進数の関数アドレスマッピング情報を保存する中継ファイルが含まれており、すべてのDebugのsymbolsはこのファイル(ファイル名、関数名、行番号などを含む)に含まれているので、デバッグシンボル情報ファイルとも呼ばれます.
一般的に、Xcodeプロジェクトはコンパイルするたびに、新しいものが生成される.dSYMファイル.したがって、Appの各リリースでは、対応するバックアップが必要となる.dSYMファイルは、後でデバッグして問題を特定するために使用されます.
注意:プロジェクトはコンパイルされるたびに、.appと.dSYMペアが出現し、両者は同一のUUID値を有し、同一のコンパイルされた生成物であることを示す.UUID値は、dwarfdump-uuidを使用して確認できます.
 $ dwarfdump --uuid XX.app.dSYM
 $ dwarfdump --uuid XX.app/XX

では、問題が来ました!
2.記号表は何に使いますか.
XcodeがデバッグAppを開発する際、クラッシュの問題が発生すると、開発者はXcodeのデバッガの位置決め分析を直接使用することができます.
しかし、Appがオンラインにリリースされると、開発者はデバッグすることができず、システムが記録したクラッシュログを分析することで問題を特定するしかない.このクラッシュログファイルでは、Appエラーの関数メモリアドレスが指摘され、これらの関数アドレスは.dSYMファイルで特定のファイル名、関数名、行番号情報を見つけたのは、シンボルテーブルの重要な役割です.
実際、XcodeのOrganizerを使用してクラッシュログを表示する場合も、自動的にローカルに格納されます.dSYMファイルは符号化されています.また、クラッシュログにもUUID情報があり、このUUIDと対応する.dSYMファイルは一致しています.すなわち、3つのUUIDが一致している場合にのみ、関数アドレスを正しく符号化することができます.
3.シンボルテーブルはどのように生成しますか?
一般に、Xcodeプロジェクトのデフォルトの構成はコンパイル後に生成する.dSYM、開発者は構成を追加する必要はありません.
プロジェクトのBuild Settingsに関する構成は次のとおりです.
    Generate Debug Symbols = Yes
    Debug Information Format = DWARF with dSYM File

異なるコンパイルパッケージ方式を採用し、生成する.dSYMファイルのパスも異なります.
次に、一般的なコンパイル・パッケージのいくつかを示します.
1、xcodebuildでパッケージをコンパイルする
Xcodeでプロジェクトをコンパイルすると、プロジェクトディレクトリの下のbuild/ClonfigurationName-iphoneosディレクトリの下で生成されます.appと.app.dSYMファイル.
xcodebuildコマンドを使用してコンパイルパッケージを作成する場合は、コンパイル結果の格納パスを指定できます.appと.app.dSYM生成.
一般的に、パッケージパブリケーションの場合、xcodebuildを使用してパッケージをコンパイルすることをお勧めします.appと.app.dSYMのマッチングメモリは、避ける.app.dSYMファイルが紛失した場合.
2、XcodeのArchiveでエクスポート
開発者がXcodeのArchiveエクスポート機能を使用してパッケージ化する場合、OrganizerのProjectsビューに切り替え、対応するプロジェクトのDerived Dataパスを表示し、現在のエクスポートプロセスで生成するものを見つけることができる.appと.app.dSYMファイル
3、makeでパッケージをコンパイルする
開発チームがXcodeコンパイルパッケージではなくmakeコンパイルで生成する場合.oファイルをパッケージ化してパブリッシュします.この場合、コンパイルプロセスは存在しない.dSYMファイル生成.開発者はdsymutilツールを使用することができる.oファイルからシンボル情報を抽出する.
4.記号表はどう使いますか.
前述の内容から分かるように,シンボルテーブルの役割は,クラッシュ中の関数アドレスを関数名などの情報に解析することである.
開発者がクラッシュした関数アドレス情報を取得できれば,シンボルテーブルを用いて具体的なエラー位置を解析することができる.
Xcodeは、開発者が関数アドレスの符号化操作を実行するのに役立ついくつかのツールを提供しています.
たとえば、クラッシュ問題の関数アドレススタックは次のようになります.
エラーアドレススタック
    3  CoreFoundation           0x254b5949 0x253aa000 + 1096008
    4  CoreFoundation           0x253e6b68 _CF_forwarding_prep_0 + 24
    5  SuperSDKTest             0x0010143b 0x000ef000 + 74808

シンボルスタック
    3   CoreFoundation          0x254b5949 <redacted> + 712
    4   CoreFoundation          0x253e6b68 _CF_forwarding_prep_0 + 24
    5   SuperSDKTest            0x0010143b -[ViewController didTriggerClick:] + 58

説明:
ほとんどの場合,開発者が取得できるのはエラーアドレススタックであり,位置決め問題を解析するにはシンボルテーブルをさらにシンボル化する必要がある.
一部の場合,開発者はbacktraceを用いて符号化スタックを見ることもでき,エラーの関数を大まかに位置決めできるが,具体的な位置は分からない.シンボルテーブル情報を利用することで,さらに具体的なエラー位置を得ることができる.
現在、多くのクラッシュモニタリングサービスはbacktraceシンボル化スタックを表示し、可読性を高めているが、位置決め問題を分析する際には、さらにシンボル化処理が必要である.
クラッシュメッセージのUUID
0xef000 - 0x17efff SuperSDKTest armv7  <38d66f9734ca3843a2bf628bb9015a8b> /var/mobile/.../SuperSDKTest.app/SuperSDKTest

次に、2つのツールを使用してシンボル化の試みを行います.
1、symbolicatecrash
Symbolicatecrashはスタックアドレスを符号化するスクリプトで、入力パラメータはアップルの公式フォーマットのクラッシュログとローカルです.dSYMファイル、実行方法は以下の通りです.
$ symbolicatecrash XX.crash [XX.app.dSYM] > xx.sym.crash#  .dSYM , 

symbolicatecrashツールの使用の制限は、公式フォーマットのクラッシュログしか分析できないことであり、具体的なデバイスからエクスポートする必要があり、取得も操作も容易ではありません.また、シンボル化の結果も具体的な行番号情報がなく、シンボル化に失敗することもよくあります.実際にXcodeのOrganizerにはsymbolicatecrashツールが内蔵されているので、開発者はシンボル化されたエラーログを直接見ることができます.
2、atos
より一般的には,開発者はエラースタック情報を取得することができ,atosツールを用いてアドレスに対応する具体的なシンボル情報を見つけることができる.
atosは実際にアドレスを関数名(行番号を含む)に変換できるツールであり、その実行方法は以下の通りである.
$ xcrun atos -o executable -arch architecture -l loadAddress
  address ...

説明:
loadAddressは関数の動的ロードアドレスを表し、クラッシュアドレススタックの+番号の前のアドレス、すなわち0 x 000 ef 000に対応する
addressは、ランタイムアドレス、対応するクラッシュアドレススタックの最初のアドレス、すなわち0 x 010143 bを表す
実際,クラッシュアドレススタックにおける+番号前後のアドレス加算はランタイムアドレス,すなわち0 x 000 ef 000+74808=0 x 010143 bである.
コマンドクエリアドレスのシンボルを実行すると、次の結果が表示されます.
$ xcrun atos -o SuperSDKTest.app.dSYM/Contents/Resources/DWARF/SuperSDKTest -arch armv7 -l 0x000ef000
0x0010143b
-[ViewController didTriggerClick:] (in SuperSDKTest) (ViewController.m:35)

開発者は具体的な運用において,スクリプトを1つ作成することで符号化エラーアドレススタックを実現できる.
5.結語
実際のプロジェクト開発では、システムが記録したクラッシュログやエラースタックに依存するため、クラッシュ問題の分析位置決めは、ローカル開発デバッグ段階では問題ありません.
パブリッシュされたオンラインバージョンでクラッシュの問題が発生した場合、開発者はエラースタックを即座に正確に取得できません.一般的に、開発者は第三者のクラッシュ監視サービス(テンセントBuglyなど)にアクセスし、オンラインバージョンのクラッシュ問題の記録と追跡を実現している.
現在、国内外で崩壊監視サービスを提供している製品はいくつかあり、崩壊問題の統計的には伯仲しない可能性がある.しかし、自動シンボル化機能を提供する製品はほとんどなく、ほとんどのクラッシュ問題のスタックは単純なシンボル化で可読性を向上させ、問題の行番号情報を迅速に特定することはできません.
テンセントBuglyはアドレススタックのシンボル化機能のクラッシュ監視サービスを提供し、開発者が対応するシンボルテーブル情報を配置すれば、Buglyサービスは自動的にエラーアドレススタックをシンボル化し、エラー位置がはっきり見え、分を分けてクラッシュ問題を位置決めし、解決する.