Android NDK, API düzeyi 27'den (Android O MR 1) itibaren Adres Temizleyici'yi (ASan olarak da bilinir) destekler.
ASan, yerel koddaki bellek hatalarını algılamaya yönelik, derleyici tabanlı hızlı bir araçtır. ASan şunları tespit eder:
- Yığın ve yığın arabellek taşması/altında akış
- Boşaltma sonrasında yığın kullanımı
- Kapsam dışında yığın kullanımı
- İki kat serbest/serbest
ASan'ın CPU ek yükü yaklaşık 2x, kod boyutu ek yükü% 50 ile 2x arasındadır ve bellek ek yükü büyüktür (ayırma kalıplarınıza bağlı olarak 2x).
Sample App
Örnek uygulama, asan için oluşturma varyantının nasıl yapılandırılacağını göstermektedir.
Topluluk
Adres Temizleyici ile uygulamanızın yerel (JNI) kodunu oluşturmak için aşağıdakileri yapın:
NK-build
Application.mk dosyanızda:
APP_STL := c++_shared # Or system, or none.
APP_CFLAGS := -fsanitize=address -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=address
Android.mk dosyanızdaki her modül için:
LOCAL_ARM_MODE := arm
Yapay Zeka
Modülünüzün build.gradle dosyasında:
android {
defaultConfig {
externalNativeBuild {
cmake {
// Can also use system or none as ANDROID_STL.
arguments "-DANDROID_ARM_MODE=arm", "-DANDROID_STL=c++_shared"
}
}
}
}
CMakeLists.txt dosyanızdaki her bir hedef için:
target_compile_options(${TARGET} PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -fsanitize=address)
Çalıştır
Android O MR1 (API düzeyi 27) sürümünden itibaren uygulamalar, uygulama işlemini sarmalayan veya değiştirebilen bir sarmalama kabuk komut dosyası sağlayabilir. Bu işlem, hata ayıklaması yapılabilecek bir uygulamanın, uygulama başlatma işlemlerini özelleştirmesini ve böylece üretim cihazlarında ASan'ın kullanılmasını sağlar.
- Uygulama manifest dosyasına
android:debuggable
ekleyin. - Uygulamanızın
build.gradle
dosyasındauseLegacyPackaging
öğesinitrue
olarak ayarlayın. Daha fazla bilgi için sarma kabuk komut dosyası kılavuzuna bakın. - Uygulama modülünüzün
jniLibs
öğesine ASan çalışma zamanı kitaplığını ekleyin. src/main/resources/lib
dizininizdeki her dizine aşağıdaki içeriklere sahipwrap.sh
dosyalarını ekleyin.#!/system/bin/sh HERE="$(cd "$(dirname "$0")" && pwd)" export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1 ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so) if [ -f "$HERE/libc++_shared.so" ]; then # Workaround for https://github.com/android-ndk/ndk/issues/988. export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so" else export LD_PRELOAD="$ASAN_LIB" fi "$@"
Projenizin uygulama modülünün app
olarak adlandırıldığı varsayıldığında son dizin yapınızın şunları içermesi gerekir:
<project root>
└── app
└── src
└── main
├── jniLibs
│ ├── arm64-v8a
│ │ └── libclang_rt.asan-aarch64-android.so
│ ├── armeabi-v7a
│ │ └── libclang_rt.asan-arm-android.so
│ ├── x86
│ │ └── libclang_rt.asan-i686-android.so
│ └── x86_64
│ └── libclang_rt.asan-x86_64-android.so
└── resources
└── lib
├── arm64-v8a
│ └── wrap.sh
├── armeabi-v7a
│ └── wrap.sh
├── x86
│ └── wrap.sh
└── x86_64
└── wrap.sh
Yığın izleri
Address Sanitizer'ın her malloc
/realloc
/free
aramada yığını gevşetmesi gerekir. Burada iki seçenek vardır:
"Hızlı" bir kare işaretçisine dayalı sarmalama açma aracı. Bu, bina bölümündeki talimatları izleyerek kullanılır.
"Yavaş" bir CFI gevşetme aracı. ASan bu modda
_Unwind_Backtrace
kullanır. Yalnızca, normalde varsayılan olarak etkin olan-funwind-tables
öğesini gerektirir.
Hızlı açma aracı, Malloc/realloc/free için varsayılandır. Yavaş açıcı, önemli yığın izlemeler için varsayılan seçenektir. Yavaş çözücü, wrap.sh dosyanızdaki ASAN_OPTIONS
değişkenine fast_unwind_on_malloc=0
eklenerek tüm yığın izlemeler için etkinleştirilebilir.