HWASan aracı bir bellek hatası tespit ettiğinde, işlem abort() ile sonlandırılır ve stderr ve logcat'e bir rapor yazdırılır. Android'deki tüm yerel çökmeler gibi, HWASan hataları /data/tombstones
altında bulunabilir.
Normal yerel çökmelerle karşılaştırıldığında HWASan, mezar taşının üst kısmına yakın bir yerde bulunan "İptal mesajı" alanında ekstra bilgi taşır. Aşağıdaki örnek yığın tabanlı kilitlenmeye bakın (yığın hataları için, yığına özgü bölümler için aşağıdaki nota bakın).
Örnek rapor
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys' Revision: 'DVT1.0' ABI: 'arm64' Timestamp: 2019-04-24 01:13:22+0000 pid: 11154, tid: 11154, name: sensors@1.0-ser >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<< signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … regular crash dump follows …]
Bu, birAdresSanitizer raporuna çok benzer. Bunlardan farklı olarak, neredeyse tüm HWASan hataları "etiket uyuşmazlığıdır", yani bir işaretçi etiketinin karşılık gelen bellek etiketiyle eşleşmediği bir bellek erişimidir. Bu aşağıdakilerden biri olabilir
- yığın veya yığın üzerinde sınırların dışında erişim
- yığında serbest kaldıktan sonra kullanın
- yığına döndükten sonra kullan
Bölümler
HWASan raporunun her bir bölümünün açıklaması aşağıdadır:
Erişim Hatası
Aşağıdakiler de dahil olmak üzere hatalı bellek erişimiyle ilgili bilgileri içerir:
- Erişim Türü ("OKU" ve "YAZMA")
- Erişim boyutu (kaç bayta erişilmeye çalışıldığı)
- Erişimin konu numarası
- İşaretçi ve bellek etiketleri (gelişmiş hata ayıklama için)
Yığın İzlemeye Erişim
Kötü bellek erişiminin yığın izlemesi. Sembolize etmek için Sembolizasyon bölümüne bakın.
Neden
Kötü erişimin potansiyel nedeni. Birden fazla aday varsa bunlar azalan olasılığa göre listelenir. Olası nedene ilişkin ayrıntılı bilgilerin önünde yer alır. HWASan aşağıdaki nedenleri teşhis edebilir:
- ücretsiz kullanım sonrası
- yığın etiketi uyuşmazlığı: bu, dönüş sonrası yığın kullanımı / kapsam sonrası kullanım veya sınırların dışında olabilir
- yığın arabellek taşması
- küresel taşma
Bellek Bilgileri
HWASan'ın erişilen bellek hakkında bildiklerini açıklar ve hata türüne göre farklılık gösterebilir.
Hata Türü | Neden | Rapor Formatı |
---|---|---|
etiket uyuşmazlığı | ücretsiz kullanım sonrası | <address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
yığın arabellek taşması | Bunun aynı zamanda bir alt akış olabileceğini de unutmayın.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: | |
yığın etiketi uyuşmazlığı | Yığın raporları taşma/eksiklik ve iade sonrası kullanım hataları arasında ayrım yapmaz. Ayrıca hatanın kaynağı olan yığın tahsisini bulmak için çevrimdışı simgeleştirme adımı gereklidir. Aşağıdaki yığın raporlarını anlama bölümüne bakın. | |
geçersiz-ücretsiz | ücretsiz kullanım sonrası | Bu çifte ücretsiz bir hatadır. İşlem kapatıldığında bu durum meydana gelirse, bu bir ODR ihlali anlamına gelebilir.<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
adresi tanımlayamıyorum | Ya vahşi bir serbest (daha önce tahsis edilmemiş olan boş hafıza) ya da tahsis edilen hafıza HWASan'ın boş arabelleğinden çıkarıldıktan sonra bir çift boş. | |
0x… HWAsan gölge belleğidir. | Uygulama HWASan'ın dahili hafızasını boşaltmaya çalıştığı için bu kesinlikle ücretsiz bir şey. |
Serbestleştirme Yığın Takibi
Belleğin serbest bırakıldığı yerin yığın izi. Yalnızca ücretsiz veya geçersiz olmayan hatalar için kullanılabilir. Sembolize etmek için Sembolizasyon bölümüne bakın.
Tahsis Yığın Takibi
Belleğin nereye tahsis edildiğine dair yığın izleme. Sembolize etmek için Sembolizasyon bölümüne bakın.
Gelişmiş Hata Ayıklama Bilgileri
HWASan raporu ayrıca (sırasıyla) aşağıdakiler dahil olmak üzere bazı gelişmiş hata ayıklama bilgilerini de içerir:
- Süreçteki iş parçacıklarının listesi
- Süreçteki iş parçacıklarının listesi
- Arızalı hafızanın yakınındaki hafıza etiketlerinin değeri
- Bellek erişimi noktasındaki kayıtların dökümü
Bellek Etiketi Dökümü
Etiket hafıza dökümü, işaretçi etiketiyle aynı etikete sahip yakındaki hafıza tahsislerini aramak için kullanılabilir. Bunlar büyük bir sapma ile sınır dışı erişime işaret edebilir. Bir etiket 16 bayt belleğe karşılık gelir; işaretçi etiketi adresin ilk 8 bitidir. Etiket hafıza dökümü ipuçları verebilir; örneğin aşağıdaki sağdaki arabellek taşmasıdır:
tags: ad/5c (ptr/mem) [...] Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: 0e 0e 0e 57 20 20 20 20 20 2e 5e 5e 5e 5e 5e b5 =>0x006f33ae2000: f6 f6 f6 f6 f6 4c ad ad ad ad ad ad [5c] 5c 5c 5c 0x006f33ae2010: 5c 04 2e 2e 2e 2e 2e 2f 66 66 66 66 66 80 6a 6a Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: ab 52 eb .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: .. .. .. .. .. .. .. .. .. .. .. .. [..] .. .. .. 0x006f33ae2010: .. 5c .. .. .. .. .. .. .. .. .. .. .. .. .. ..(işaretçi etiketiyle eşleşen, soldaki 6 × 16 = 96 baytlık “reklam” etiketlerinin dizisine dikkat edin).
Bir ayırmanın boyutu 16'nın katı değilse, boyutun geri kalanı bellek etiketi olarak, etiket ise kısa granül etiketi olarak depolanır. Yukarıdaki örnekte, kalın harflerle gösterilen tahsis etiketli reklamın hemen ardından, 5 × 16 + 4 = 84 baytlık 5c etiketi tahsisimiz var.
Sıfır bellek etiketi (ör. tags: ad/ 00 (ptr/mem)
) genellikle dönüşten sonra yığın kullanımında bir hata olduğunu gösterir.
Kayıt Dökümü
HWASan raporlarındaki kayıt dökümü, geçersiz bellek erişimini gerçekleştiren gerçek talimata karşılık gelir. Bunu normal Android sinyal işleyicisinden başka bir kayıt dökümü takip eder - ikincisini dikkate almayın , HWASan abort() öğesini çağırdığında alınır ve hatayla ilgili değildir.
Sembolizasyon
Yığın izlemelerinde işlev adlarını ve satır numaralarını almak (ve kapsam sonrası kullanım hataları için değişken adlarını almak) için çevrimdışı bir simgeleştirme adımı gerekir.
İlk kurulum: llvm-symbolizer'ı yükleyin
Sembolize etmek için sisteminizde llvm-symbolizer kurulu olmalı ve $PATH adresinden erişilebilir olmalıdır. Debian'da sudo apt install llvm
komutunu kullanarak kurabilirsiniz.
Sembol dosyalarını edinin
Sembolizasyon için semboller içeren ayrıştırılmamış ikili dosyalara ihtiyacımız var. Bunların nerede bulunabileceği yapının türüne bağlıdır:
Yerel yapılar için sembol dosyaları out/target/product/<product>/symbols/
konumunda bulunabilir.
AOSP yapıları için (örn. Flashstation'dan flashlanmış), yapılar Android CI'da bulunabilir. Derlemenin "Yapılar"ında bir "${ÜRÜN}-symbols-${BUILDID}.zip` dosyası olacaktır.
Kuruluşunuzun dahili derlemeleri için, sembol dosyalarını edinme konusunda yardım amacıyla kuruluşunuzun belgelerine bakın.
Sembolize et
hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Yığın Raporlarını Anlamak
Yığın değişkenlerinde meydana gelen hatalar için HWASan raporu aşağıdaki gibi ayrıntıları içerecektir:
Cause: stack tag-mismatch Address 0x007d4d251e80 is located in stack of thread T64 Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000) Previously allocated frames: record_addr:0x7df7300c98 record:0x51ef007df3f70fb0 (/apex/com.android.art/lib64/libart.so+0x570fb0) record_addr:0x7df7300c90 record:0x5200007df3cdab74 (/apex/com.android.art/lib64/libart.so+0x2dab74) [...]
Yığın hatalarının anlaşılmasını sağlamak için HWASan, geçmişte meydana gelen yığın çerçevelerinin kaydını tutar. HWASan şu anda bunu hata raporunda insanların anlayabileceği içeriğe dönüştürmüyor ve ek bir simgeleştirme adımı gerektiriyor.
ODR İhlalleri
HWASan tarafından bildirilen bazı ücretsiz kullanım sonrası hatalar aynı zamanda Tek Tanım Kuralı (ODR) ihlaline de işaret edebilir. Aynı değişken aynı programda birden çok kez tanımlandığında ODR ihlali meydana gelir. Bu aynı zamanda değişkenin birden fazla kez imha edildiği anlamına gelir ve bu da serbest kullanım sonrası hatasına yol açabilir.
Sembolleştirmeden sonra, ODR ihlalleri, hem geçersiz erişim yığınında hem de "burada serbest bırakıldı" yığınında __cxa_finalize
ile bir serbest bırakma sonrası kullanım gösterir. "Daha önce burada tahsis edilmiş" yığını __dl__ZN6soinfo17call_constructorsEv
içerir ve programınızda yığının üst kısmındaki değişkeni tanımlayan konumu işaret etmelidir.
ODR'nin ihlal edilmesinin bir nedeni statik kitaplıkların kullanılmasıdır. Bir C++ globalini tanımlayan statik bir kitaplık birden çok paylaşılan kitaplığa veya yürütülebilir dosyaya bağlanırsa, aynı sembolün birden çok tanımı aynı adres alanında mevcut olabilir ve bu da bir ODR hatasına neden olur.
Sorun giderme
"HWAddressSanitizer adresi daha detaylı açıklayamıyor."
Bazen HWASan'da geçmiş bellek tahsisleri hakkında bilgi için yeterli alan kalmayabilir. Bu durumda rapor, anlık bellek erişimi için yalnızca bir yığın izlemesi ve ardından bir not içerecektir:
HWAddressSanitizer can not describe address in more detail.
Bazı durumlarda bu durum, testi birden çok kez çalıştırarak çözülebilir. Diğer bir seçenek de HWASan geçmiş boyutunu artırmaktır. Bu, genel olarak build/soong/cc/sanitize.go
dosyasında ( hwasanGlobalOptions
arayın) veya işlem ortamınızda (mevcut ayarları görmek için adb shell echo $HWASAN_OPTIONS
deneyin) yapılabilir.
Bu durum, erişilen belleğin eşlenmemesi veya HWASan'ın farkında olmayan bir ayırıcı tarafından tahsis edilmemesi durumunda da meydana gelebilir. Bu durumda kilitlenme başlığında listelenen mem
etiketi genellikle 00
olacaktır. Mezar taşının tamamına erişiminiz varsa, adresin hangi eşlemeye (varsa) ait olduğunu öğrenmek için bellek haritaları dökümüne başvurmanız faydalı olabilir.
"aynı başlıkta iç içe geçmiş hata"
Bu, HWASan kilitlenme raporu oluşturulurken bir hata olduğu anlamına gelir. Bunun nedeni genellikle HWASan çalışma zamanındaki bir hatadır; lütfen bir hata bildirin ve mümkünse sorunun nasıl yeniden oluşturulacağına ilişkin talimatlar sağlayın.