Flutter と デバッグシンボル(dSYM)
デバッグシンボルとは
人間が理解できるソースコード(開発で書いているコード)をバイナリデータ(機械語)にコンパイルする過程で、ファイルサイズの削減やパフォーマンス向上を目的とした最適化が行われる。このとき、変数名や関数名といったいわゆるシンボル情報も除去されてしまう。
アプリの起動中などのバイナリデータの実行中には、クラッシュが起こることがあり、このクラッシュ時の情報としてメモリアドレスやスタックトレースをそのバイナリデータを実行しているOSは取得してくれている。
しかし、このOSが取得してくれている情報をそのまま見ても人間には理解するのは困難な情報になっている。このときに、シンボル情報の対照表のようなものがあれば、この理解困難なメモリアドレスやスタックトレースの情報を人間が理解しやすい情報へ翻訳することができる。
この対照表情報こそがデバッグシンボルと呼ばれる情報ファイルである。
また、この翻訳のことをシンボル化(シンボライぜーション)という。
具体的には以下のような情報が含まれている。
- 関数名(メソッド名)
- 変数名
- 行番号
- 型情報
ちなみに、dSYM(ディーワイエスエム)というのは、Appleの開発環境(iOSやmacOSなど)で使用される呼び名なだけで、デバッグやクラッシュレポートの解析を行うという目的は同じ。
Flutterでデバッグシンボルの取得
Flutter(Android, iOS)でもアプリをビルドするときに、同時にデバッグシンボルも生成されている。
Android
Androidアプリをビルドするときは、まず ProGuardやR8を使用してコードの難読化が行われる。
その後にバイナリデータにコンパイルされるが、このときにbuild/app/outputs/mapping/release/mapping.txt
というファイルが生成されるが、このファイルがクラッシュレポートをシンボル化するときに必要なファイルとなる。
Play Console にアプリをアップロードするとデバッグシンボルをアップロードされていないという警告が出ることがあるが、このときに要求されるのは mapping.txt
だけでなく、build/app/intermediates/merged_native_libs/release/out/lib
フォルダに生成されるarm64-v8a
、armeabi-v7a
、x86_64
の3つを.zip
ファイルに圧縮したものである。
これらはネイティブコードのクラッシュ解析に必要らしい。。。
iOS
flutter build ios
コマンドなどでビルドを行うと以下のパスに dSYMディレクトリが生成される。
build/ios/Release-iphoneos/Runner.app.dSYM
OSが取得してくれるクラッシュレポートを見る方法は以下のような方法がある
- XcodeのOrganizerから取得
- App Store Connectからダウンロード
- CLIを通じて取得
Firebase Crashlytics
Firebase Crashlyticsはクラッシュレポートを見るための有名なサービスであり、これの導入だけでも十分であることが多い。(はず)
Android
FlutterプロジェクトにFirebase Crashlyticsを正しく導入すると、Androidアプリのビルド時に自動でデバッグシンボル情報を取得してくれるらしく、自分でデバッグシンボルをアップロードするような手間はない。
iOS
FlutterプロジェクトにFirebase Crashlytics導入し、初めてのクラッシュを発生させるとFirebaseのGUIなどからクラッシュレポートが見えるようになる。これで連携は完了しているが、iOSの方は dSYMをアップロードする必要がある。
あとがき
開発現場とかだと、CI/CDパイプラインが手配されていることが多く、そうなるとデバッグシンボルだけマニュアルアップロードするわけにもいかず、このパイプライン中にこれもアップロードされる必要が出てくる。
GitHub Actions の話になってしまうが、Androidの方は、このアクションを使用することで、Play Consoleのアップロード時にデバッグシンボル情報もアップロードしてくれる。
iOSは Xcode の Build Phase
セクションでアップロードのスクリプトを実行することがよくあるみたい。。。
Discussion