LoginSignup
2

More than 3 years have passed since last update.

posted at

updated at

Android + cmake で ASAN(Address Sanitizer)を使う

API level 27 から Android でも ASAN(Address Sanitizer)が使えるようになりました.
(APL level 24 くらいから使えたような気もしますが, セットアップのしかたが変わったようです)

ビルド

ドキュメント通りにすればいけます.
特段, gradle や CMake での ASAN 専用設定オプションはありません.
CFLAGS/LDFLAGS に直接 -fsanitize=address あたりを指定します.

APK の作成

libclang_rt.asan-*-android.so ファイルは NDK のパッケージにあります. jniLibs/<arch> に入れます.

wrap.sh ファイルは, resources/lib/<arch> フォルダに入れます(res でもいいかもしれません)
(jniLibs/<arch> に置いても, .so ファイルしか APK にコピーされないため)

APK にパッケージングされたら, lib/<arch>/ に .so と wrap.sh が置かれるはずです.

実行時

asan エラーがでると, logcat に

ERROR: AddressSanitizer: SEGV ...

などとエラーとスタックトレースを出してくれます.
ただ, debug ビルドしてもソースコードなどの行は出してくれません.

symbolize

How to Get meaningful stack trace in Android
https://github.com/google/sanitizers/issues/984

スタックのファイル名や行番号を出すには, logcat の結果を, host 側で llvm-symbolizer 走らせて取得する必要があります.

実機で /system/bin/ などに llvm-symbolizer を入れて動かしたいところですが, 現状ではこれを行うには rooted or ASOP が必要なので, Vulkan/GLES を使うなどグラフィックスメインのアプリ開発では選択肢にはなり得ません.

一応 NDK のパッケージに実デバイスで動く llvm-symbolizer のリクエストは上がっています.

Add device llvm-symbolizer to NDK
https://github.com/android/ndk/issues/753

TODO

  • logcat で ASAN スタックトレースでソースコードが表示されるようにできないか調べる.
    • host で llvm-symbolizer を動かす
  • wrap.sh で他の .so も有効にする方法を試す(Vulkan validation layers, tsan, msan, etc)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2