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) ile çalışın. ve daha büyük bir ek RAM yüküne sahip benzer bir araç yardımcı olan bir metrik. 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 yöntemi 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. Bu,
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
hedefLOCAL_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.