Adres Temizleyici

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.

  1. Uygulama manifest dosyasına android:debuggable ekleyin.
  2. Uygulamanızın build.gradle dosyasında useLegacyPackaging öğesini true olarak ayarlayın. Daha fazla bilgi için sarma kabuk komut dosyası kılavuzuna bakın.
  3. Uygulama modülünüzün jniLibs öğesine ASan çalışma zamanı kitaplığını ekleyin.
  4. src/main/resources/lib dizininizdeki her dizine aşağıdaki içeriklere sahip wrap.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:

  1. "Hızlı" bir kare işaretçisine dayalı sarmalama açma aracı. Bu, bina bölümündeki talimatları izleyerek kullanılır.

  2. "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.