Adres Temizleyici

.

AddressSanitizer (ASan), bir kullanıcının konumunu algılamaya yönelik hızlı derleyici tabanlı bir araçtır. bellek hatalarını gidermeye çalışı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, hem 32 bit hem de 64 bit ARM ile x86 ve x86-64'te çalışır. ASan'ın ek CPU yükü Yaklaşık 2 kat, kod boyutu ek yükü% 50 ila 2 kat ve ek bellek yükü de fazladır. (ayırma kalıplarınıza bağlıdır, ancak 2x sırasına bağlıdır).

Android 10 ve AArch64'te AOSP ana dalı Donanım destekli AddressSanitizer (HWASan) desteği varsa daha büyük bir ek RAM yüküne ve daha büyük hata payı ve farkı gözlemlediniz. HWASan, dönüş sonrasında yığın kullanımını ve ayrıca tespit etti.

HWASan, benzer CPU ve kod boyutu ek yüküne sahiptir ancak çok daha az ek RAM yüküne sahiptir (%15). HWASan deterministik değildir. Yalnızca 256 olası etiket değeri vardır, dolayısıyla sabit bir %0,4 vardır ihtimalini ifade eder. HWASan, ASan'ın sabit boyuta sahip kırmızı bölgeleri taşma işlemlerini ve sınırlı kapasiteli karantinayı tespit ederek ücretsiz kullanım, Bu nedenle, HWASan için taşmanın ne kadar büyük olduğunu veya belleğin ne kadar zaman önce kararlaştırıldı. Bu sayede HWASan, ASan'dan daha iyidir. Web sitemiz g.co/newsinitiative/labs üzerinden tasarım: HWASan veya Android'de HWASan kullanımı hakkında bilgi edinebilirsiniz.

ASan, yığın/genel taşma algılar ek bellek yüküne sahip olan hızlı bir çalışma yöntemidir.

Bu dokümanda, Android'in tüm parçalarının/tüm parçalarının nasıl oluşturulacağı ve çalıştırılacağı San. ASan ile bir SDK/NDK uygulaması oluşturuyorsanız Adres Temizleyici .

Bağımsız yürütülebilir dosyaları ASan ile temizleyin

Şuraya LOCAL_SANITIZE:=address veya sanitize: { address: true } ekleyin: derleme kuralını yazın. Kodda mevcut örnekleri arayabilir veya hazırlayabiliriz.

Bir hata algılandığında ASan, standart çıkışını ve logcat komutunu ayarlar, ardından da işlemi kilitler.

Paylaşılan kitaplıkları ASan ile arındırın

ASan'ın çalışma biçimi nedeniyle, ASan ile oluşturulan bir kütüphane yalnızca ASan ile oluşturulan yürütülebilir bir dosyadır.

Tüm yürütülebilir dosyalarda değil, birden çok yürütülebilir dosyada kullanılan paylaşılan bir kitaplığı kitaplığın iki kopyasına ihtiyacınız olacak. İlgili içeriği oluşturmak için kullanılan bunu yapmanın önerilen yolu, şunu eklemektir: Android.mk açıklamanız gerekiyor:

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

Bu işlem, kitaplığı şu yerine /system/lib/asan konumuna getirir: /system/lib. Ardından, yürütülebilir dosyanızı şununla çalıştırın:

LD_LIBRARY_PATH=/system/lib/asan

Sistem arka plan programları için aşağıdakileri uygun bölüme ekleyin: /init.rc veya /init.$device$.rc.

setenv LD_LIBRARY_PATH /system/lib/asan
.

İşlemde /system/lib/asan kitaplığının kullanıldığını doğrulayın (varsa) /proc/$PID/maps okuyarak yavaştır. Aksi halde, (SELinux'u devre dışı bırakmak için:

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 izlemeler

ASan, yığın kaydetmek için hızlı, kare işaretçisine dayalı bir açıcı kullanır izlemesine olanak tanır. En sık çerçeve işaretçileri olmadan tasarlandı. Bunun sonucunda, sıklıkla yalnızca bir veya iki anlamlı kare kullanabilirsiniz. Bu sorunu düzeltmek için kitaplığı ASan (önerilir!) veya şunları içeren:

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

Alternatif olarak işlem sırasında ASAN_OPTIONS=fast_unwind_on_malloc=0 değerini de ayarlayabilirsiniz bahsedeceğim. İkincisi, çalışma hızınıza bağlı olarak yardımcı olabilir.

Sembol

Başlangıçta ASan raporları, ikili programlarda ofsetlere referanslar içerir ve kitaplıklar. Kaynak dosya ve satır bilgilerini edinmenin iki yolu vardır:

  • llvm-symbolizer ikili programının /system/bin içinde bulunduğundan emin olun. llvm-symbolizer, şuradaki kaynaklardan geliştirildi: third_party/llvm/tools/llvm-symbolizer.
  • Raporu external/compiler-rt/lib/asan/scripts/symbolize.py aracılığıyla filtreleyin komut dosyası.

İkinci yaklaşım, daha fazla veri (yani file:line konum) sağlayabilir. Bunun nedeni, ana makinede sembolik kitaplıkların kullanılabilirliği.

Uygulamalarda ASan

ASan, Java kodunu göremez ancak JNI'deki hataları algılayabilir kitaplıklar. Bunun için yürütülebilir dosyayı ASan ile derlemeniz gerekir. bu durum /system/bin/app_process(32|64). Bu Cihazdaki tüm uygulamalarda ASan'ı aynı anda etkinleştirir. ancak 2 GB RAM'e sahip bir cihaz bunu yapabilir.

LOCAL_SANITIZE:=address adlı kişiyi şuraya ekle: frameworks/base/cmds/app_process içinde app_process derleme kuralı Yoksay Şimdilik aynı dosyada app_process__asan hedefini ( halen vardır).

Şu öğenin service zygote bölümünü düzenleyin: eklemek için uygun system/core/rootdir/init.zygote(32|64).rc dosyası sonra, class main içeren girintili satır blokuna aynı miktarda girintilendirildi:

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

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

Sarmalama özelliğini kullanma

Bir önceki bölümdeki yaklaşım, ASan'ı sisteme ekleyebilirsiniz (aslında Zygot'un işlemi) ekleyebilirsiniz. ASan ile yalnızca bir (veya birkaç) uygulama çalıştırmak mümkündür. daha yavaş uygulama başlatma için bir miktar ek bellek yüküne neden olur.

Bunu, uygulamanızı wrap. özelliğiyle başlatarak yapabilirsiniz. Aşağıdaki örnekte Gmail uygulaması ASan altında çalıştırılı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 hücresini yeniden yazar ve /system/bin/asan/app_process gibi San. Ayrıca başına /system/lib/asan ekler. dinamik kitaplık arama yolunu izler. Böylece, ASan enstrümanlı /system/lib/asan kitaplıkları, normal kitaplıklar yerine tercih edilir asanwrapper ile çalışırken /system/lib içinde.

Bir hata bulunursa uygulama kilitlenir ve rapor şu adrese yazdırılır: görebilirsiniz.

SANITIZE_HEDEFİ

Android 7.0 ve sonraki sürümler, tüm Android platformunu oluşturma desteğini içerir. Aynı anda birden fazla arama yapabilirsiniz. (Android 9'dan daha yeni bir sürüm oluşturuyorsanız HWASan daha iyi bir seçenektir.)

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

make -j42
SANITIZE_TARGET=address make -j42

Bu modda, userdata.img ek kitaplıklar içerir ve yanıp söndü. Aşağıdaki komut satırını kullanın:

fastboot flash userdata && fastboot flashall

Bu şekilde iki grup paylaşılan kitaplık oluşturulur: /system/lib (ilk yapma çağrısı) ve ASan tarafından /data/asan/lib (ikinci marka çağrısı). Yürütülebilir dosya türleri diğer derlemelerin üzerine yazılır. A San Enstrümanlı yürütülebilir dosyalar aşağıdakileri içeren farklı bir kitaplık arama yolu alır /system/lib tarihinden önce /data/asan/lib kullanarak PT_INTERP içinde /system/bin/linker_asan.

Derleme sistemi, $SANITIZE_TARGET değeri değişti. Bu, tüm ekibin yeniden /system/lib altında yüklü ikili programları korurken hedefler.

Bazı hedefler ASan ile oluşturulamaz:

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

Bunlar gibi yürütülebilir dosyalar SANITIZE_TARGET derlemesinde atlanır ve ilk yapma çağrısındaki sürüm /system/bin içinde bırakıldı.

Bunun gibi kitaplıklar ASan olmadan oluşturulur. Bir miktar ASan içerebilir kodlardan yararlanırız.

Destekleyici belgeler