Android NDK, başlangıçtan itibaren Adres Sanitizer'ı (ASan olarak da bilinir) destekler. (Android O MR 1) kullanın.
ASan, yerel koddaki bellek hatalarını algılamaya yönelik hızlı derleyici tabanlı bir araçtır. ASan şunları algılar:
- Yığın ve yığın arabellek taşması/alt akışı
- Boş olduğunda yığın kullanımı
- Kapsam dışında yığın kullanımı
- Çift serbest/wild serbest
ASan'ın CPU ek yükü yaklaşık 2 kat, kod boyutu ek yükü% 50 ila 2 kattır. ve bellek ek yükü büyüktür (ayrma kalıplarınıza bağlıdır ancak 2x).
Sample App
Örnek uygulama asan için derleme varyantının nasıl yapılandırılacağını gösterir.
Topluluk
Adres Sanitizer ile uygulamanızın yerel (JNI) kodunu oluşturmak için takip etmek için:
ndk-kurum
Application.mk'nizde:
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
CMake
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 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'den (API düzeyi 27) itibaren bir uygulama sarmalama kabuk komut dosyasını kullanın. Bu da hata ayıklaması yapılabilir bir uygulama sunar. Bu da, üretim cihazlarında ASan kullanarak
android:debuggable
öğesini uygulama manifestine ekleyin.useLegacyPackaging
ayarla uygulamanızınbuild.gradle
dosyasındakitrue
adresine. Kabuk komut dosyasını sarmalama kılavuzuna bakın. konulu videomuzu izleyin.- ASan çalışma zamanı kitaplığını, uygulama modülünüzün
jniLibs
cihazına ekleyin. Aşağıdaki içeriğe sahip
wrap.sh
dosyalarınısrc/main/resources/lib
dizini.#!/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ığını varsayarsak son dizininiz
yapısı şunları içermelidir:
<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
Adres Temizleyici'nin, her malloc
.realloc
.free
tarihinde bir yığını rahatlatması gerekiyor
çağrısına bir tıklama URL'si eklemeniz gerekir. Burada iki seçenek vardır:
"Hızlı" çerçeve işaretçisine dayalı açıcıdan yararlanabilirsiniz. Bu, yapı bölümünde bulabilirsiniz.
Bir "yavaş" CFI açıcı. ASan bu modda
_Unwind_Backtrace
kullanır. Google yalnızca normalde varsayılan olarak etkin olan-funwind-tables
gerektirir.
Malloc/realloc/free için hızlı açıcı varsayılan ayardır. Yavaş gevşeyici ise
önemli yığın izlemeler (stack trace) için varsayılan ayardır. Yavaş açıcı özelliği tüm kullanıcılar için etkinleştirilebilir.
ASAN_OPTIONS
değişkenine fast_unwind_on_malloc=0
ekleyerek yığın izleme (stack trace)
inceleyebilirsiniz.