Google, Siyah topluluklar için ırksal eşitliği ilerletmeye kararlıdır. Nasıl olduğunu gör.
Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

AddressSanitizer

AddressSanitizer (ASan), yerel koddaki bellek hatalarını algılamak için derleyici tabanlı hızlı bir araçtır.

ASan şunları tespit ediyor:

  • Yığın ve yığın arabellek taşması / taşması
  • Ücretsiz sonra yığın kullanımı
  • Kapsam dışında yığın kullanımı
  • Çift kişilik ücretsiz / vahşi ücretsiz

ASan, hem 32 bit hem de 64 bit ARM'nin yanı sıra x86 ve x86-64 üzerinde çalışır. ASan'ın CPU yükü kabaca 2x, kod boyutu yükü% 50 ile 2x arasında ve büyük bir bellek yükü (ayırma düzenlerinize bağlı olarak, ancak 2x sırasına göre).

Android 10 ve AArch64'teki AOSP ana dalı, daha düşük RAM ek yüküne ve daha geniş bir tespit edilen hata aralığına sahip benzer bir araç olan donanım hızlandırmalı ASan'ı (HWASan) destekler. HWASan, ASan tarafından algılanan hatalara ek olarak, dönüşten sonra yığın kullanımını tespit eder.

HWASan'ın benzer CPU ve kod boyutu ek yükü vardır, ancak çok daha küçük bir RAM ek yükü vardır (% 15). HWASan belirsizdir. Yalnızca 256 olası etiket değeri vardır, bu nedenle hataların% 0,4'ünde sabit bir olasılık vardır. HWASan, ASan'ın taşmaları algılamak için sınırlı boyutlu kırmızı bölgelerine ve ücretsiz kullanımdan sonra algılamak için sınırlı kapasiteli karantinaya sahip değildir, bu nedenle HWASan'ın taşmanın ne kadar büyük olduğu veya belleğin ne kadar süre önce yer değiştirdiği önemli değildir. Bu HWASan'ı ASan'dan daha iyi yapar. HWASan'ın tasarımı veya HWASan'ın Android'de kullanımı hakkında daha fazla bilgi edinebilirsiniz .

ASan, yığın taşmalarına ek olarak yığın / genel taşmaları algılar ve minimum bellek yükü ile hızlıdır.

Bu belgede, Android parçalarının / tümünün ASan ile nasıl oluşturulacağı ve çalıştırılacağı açıklanmaktadır. ASan ile bir SDK / NDK uygulaması oluşturuyorsanız, bunun yerine Adres Temizleyici'ye bakın.

ASan ile tek tek yürütülebilir dosyaları dezenfekte etme

Yürütülebilir dosyanın oluşturma kuralına LOCAL_SANITIZE:=address veya sanitize: { address: true } ekleyin. Mevcut örnekleri bulmak veya mevcut diğer dezenfektanları bulmak için kodu arayabilirsiniz.

Bir hata tespit edildiğinde, Asan bir ayrıntılı standart çıkışa ve hem rapor yazdırır logcat ve sonra işlemi çöküyor.

ASan ile paylaşılan kütüphaneleri dezenfekte etme

ASan'ın çalışma şekli nedeniyle, ASan ile oluşturulmuş bir kütüphane yalnızca ASan ile oluşturulmuş bir yürütülebilir dosya tarafından kullanılabilir.

Hepsi ASan ile oluşturulmuş birden fazla yürütülebilir dosyada kullanılan paylaşılan bir kütüphaneyi sterilize etmek için kütüphanenin iki kopyasına ihtiyacınız vardır. Bunu yapmanın önerilen yolu, söz konusu modül için Android.mk aşağıdakileri Android.mk :

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

Bu koyar kütüphane /system/lib/asan yerine /system/lib . Ardından, çalıştırılabilir öğenizi şununla çalıştırın:

LD_LIBRARY_PATH=/system/lib/asan

Sistem deamon`lar için uygun bölüme aşağıdaki eklemek /init.rc veya /init.$device$.rc .

setenv LD_LIBRARY_PATH /system/lib/asan

/proc/$PID/maps okuyarak, işlemin /system/lib/asan kullandığını doğrulayın. Değilse, SELinux'u devre dışı bırakmanız gerekebilir:

adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID
# if it is a system service, or may be adb shell stop; adb shell start.

Daha iyi yığın izleri

ASan, programdaki her bellek ayırma ve ayırma olayı için bir yığın izlemesi kaydetmek için hızlı, kare işaretçisi tabanlı bir çözücü kullanır. Android'in çoğu çerçeve işaretçisi olmadan oluşturulmuştur. Sonuç olarak, genellikle yalnızca bir veya iki anlamlı kare elde edersiniz. Bunu düzeltmek için, kütüphaneyi ASan (önerilen!) İle veya aşağıdakilerle yeniden oluşturun:

LOCAL_CFLAGS:=-fno-omit-frame-pointer
LOCAL_ARM_MODE:=arm

Veya işlem ortamında ASAN_OPTIONS=fast_unwind_on_malloc=0 olarak ayarlayın. İkincisi, yüke bağlı olarak çok CPU yoğun olabilir.

simgeleme

Başlangıçta, ASan raporları ikili dosyalar ve paylaşılan kütüphanelerdeki ofsetlere referanslar içerir. Kaynak dosya ve satır bilgilerini almanın iki yolu vardır:

  • llvm-symbolizer ikili dosyasının /system/bin içinde bulunduğundan emin olun. llvm-symbolizer third_party/llvm/tools/llvm-symbolizer .
  • external/compiler-rt/lib/asan/scripts/symbolize.py komut dosyası aracılığıyla raporu filtreleyin.

İkinci yaklaşım, ana bilgisayarda sembolize edilmiş kitaplıkların kullanılabilir olması nedeniyle daha fazla veri sağlayabilir (yani, file:line konumları).

Uygulamalarda ASan

ASan Java kodunu göremez, ancak JNI kitaplıklarındaki hataları algılayabilir. Bunun için yürütülebilir dosyayı ASan ile oluşturmanız gerekir, bu durumda /system/bin/app_process( 32|64 ) . Bu, ASan'ın cihazdaki tüm uygulamalarda aynı anda olmasını sağlar, bu da ağır bir yüktür, ancak 2 GB RAM'e sahip bir cihaz bunu başarabilmelidir.

LOCAL_SANITIZE:=address frameworks/base/cmds/app_process içindeki app_process oluşturma kuralına frameworks/base/cmds/app_process . app_process__asan aynı dosyadaki app_process__asan hedefini yok app_process__asan (bunu okuduğunuz anda hala oradaysa).

Aynı satır tarafından girintili, class main içeren girintili satırların bloğuna aşağıdaki satırları eklemek için uygun system/core/rootdir/init.zygote( 32|64 ).rc dosyasının service zygote bölümünü system/core/rootdir/init.zygote( 32|64 ).rc :

    setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib
    setenv ASAN_OPTIONS allow_user_segv_handler=true

Derleme, adb senkronizasyonu, fastboot flash önyükleme ve yeniden başlatma.

Wrap özelliğini kullanma

Önceki bölümdeki yaklaşım ASan'ı sistemdeki her uygulamaya (aslında, Zygote sürecinin her soyundan) koyar. ASan ile yalnızca bir (veya birkaç) uygulama çalıştırmak ve daha yavaş uygulama başlatma için biraz bellek yükü işlemek mümkündür.

Bu, uygulamanızı wrap. ile başlatarak yapılabilir wrap. Emlak. Aşağıdaki örnek, ASan altında Gmail uygulamasını çalıştırır:

adb root
adb shell setenforce 0  # disable SELinux
adb shell setprop wrap.com.google.android.gm "asanwrapper"

Bu bağlamda, asanwrapper /system/bin/app_process ile oluşturulan /system/bin/asan/app_process olarak yeniden yazar. Ayrıca dinamik kütüphane arama yolunun başına /system/lib/asan ekler. Bu yolla, /system/lib/asan asan'dan ASan aracılı kütüphaneler, asanwrapper ile çalışırken /system/lib asanwrapper normal kütüphanelere tercih edilir.

Bir hata bulunursa uygulama kilitlenir ve rapor günlüğe yazdırılır.

SANITIZE_TARGET

Android 7.0 ve sonraki sürümler, ASan ile aynı anda tüm Android platformunu oluşturma desteğini içerir. (Android 9'dan daha yüksek bir sürüm oluşturuyorsanız, HWASan daha iyi bir seçimdir.)

Aynı komut ağacında aşağıdaki komutları çalıştırın.

make -j42
SANITIZE_TARGET=address make -j42

Bu modda, userdata.img fazladan kitaplık içerir ve cihaza da yanıp sönmelidir. Aşağıdaki komut satırını kullanın:

fastboot flash userdata && fastboot flashall

Bu, iki paylaşılan kütüphane seti oluşturur: /system/lib içinde normal (ilk oluşturma çağrısı) ve /data/asan/lib (ikinci oluşturma çağrısı) içinde ASan araçları. İkinci derlemedeki yürütülebilir dosyalar ilk derlemenin üzerine yazılır. ASan aracılı yürütülebilir dosyalar PT_INTERP içinde /system/bin/linker_asan kullanarak /system/bin/linker_asan /data/asan/lib öncesi /system/lib komutunu içeren farklı bir kütüphane arama yolu PT_INTERP .

Derleme sistemi, $SANITIZE_TARGET değeri değiştiğinde ara nesne dizinlerini tıkar. Bu, /system/lib altında kurulu ikili dosyaları korurken tüm hedeflerin yeniden oluşturulmasını zorlar.

ASan ile bazı hedefler oluşturulamaz:

  • Statik olarak bağlı yürütülebilir dosyalar
  • LOCAL_CLANG:=false hedefler
  • LOCAL_SANITIZE:=false SANITIZE_TARGET=address için LOCAL_SANITIZE:=false ASan'd değil SANITIZE_TARGET=address

Bu gibi yürütülebilir dosyalar SANITIZE_TARGET yapısında atlanır ve ilk başlatma çağrısından gelen sürüm /system/bin içinde bırakılır.

Bunun gibi kütüphaneler ASan olmadan inşa edilmiştir. Bağlandıkları statik kitaplıklardan bazı ASan kodları içerebilirler.

Destekleyici belgeler