HWASan aracı bir bellek hatası algıladığında işlem abort() ile sonlandırılır ve stderr ile logcat'e bir rapor yazdırılır. Android'deki tüm yerel kilitlenmeler gibi, HWASan hataları da /data/tombstones altında yer alır.
Örnek rapor
HWASan, normal yerel kilitlenmelere kıyasla, tombstone'un üst kısmına yakın Abort message alanında ek bilgiler taşır. Aşağıda, yığın tabanlı bir kilitlenme örneği verilmiştir. Yığın hataları için yığına özgü bölümlerdeki nota bakın.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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, AddressSanitizer raporuna benzer. Bunların aksine, neredeyse tüm HWASan hataları etiket uyuşmazlığı hatalarıdır. Yani, işaretçi etiketinin karşılık gelen bellek etiketiyle eşleşmediği bir bellek erişimidir. Bu, aşağıdakilerden herhangi biri olabilir:
- Yığın veya heap üzerinde sınırların dışında erişim
- Yığında serbest bırakıldıktan sonra kullanma hatası
- Yığında dönüş sonrası kullanma hatası
Bölümler
HWASan raporunun her bölümü aşağıda açıklanmıştır.
Erişim hatası
Aşağıdakiler de dahil olmak üzere hatalı bellek erişimiyle ilgili bilgileri içerir:
- Erişim türü (
READveWRITE) - Erişim boyutu (kaç bayta erişilmeye çalışıldığı)
- Erişimin ileti dizisi numarası
- İşaretçi ve bellek etiketleri (ileri düzey hata ayıklama için)
Yığın izlemeye erişme
Hatalı bellek erişiminin yığın izlemesi. Sembol oluşturmak için Sembolleştirme bölümüne bakın.
Neden
Kötü erişimin olası nedeni. Birden fazla aday varsa bunlar olasılıklarına göre azalan sırada listelenir. Olası neden hakkında ayrıntılı bilgiden önce gelir. HWASan aşağıdaki nedenleri teşhis edebilir:
- Ücretsiz kullanımdan sonra
- Yığın etiketi uyuşmazlığı (yığın kullanımı dönüşten sonra, yığın kullanımı kapsamdan sonra veya sınırların dışında olabilir)
- Yığın arabellek taşması
- Genel 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 biçimi |
|---|---|---|
| Etiket uyuşmazlığı | Ücretsiz kullanımdan sonra | Şu rapor biçimini kullanın:<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| Yığın arabellek taşması | Bunun bir taşma da olabileceğini 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 veya yetersizlik ile geri dönüşten sonra kullanma hataları arasında ayrım yapmaz. Ayrıca, hatanın kaynağı olan yığın ayırmayı bulmak için çevrimdışı sembolleştirme adımı gerekir. Yığın raporlarını anlama başlıklı makaleyi inceleyin. | |
| Geçersiz ücretsiz | Ücretsiz kullanımdan sonra | Çift serbest bırakma hatası. Bu durum, işlem kapatılırken gerçekleşirse ODR ihlali anlamına gelebilir.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| Adres açıklanamıyor | Daha önce ayrılmamış bellekten oluşan bir serbest bellek veya ayrılan bellek, HWASan'ın serbest arabelleğinden çıkarıldıktan sonraki çift serbest bellek. | |
| 0x... is HWAsan shadow memory | Uygulama, HWASan'a özgü belleği boşaltmaya çalıştığı için vahşi boşaltma işlemi yapıldı. |
Deallocation stack trace (Bellek ayırma işleminin geri alınmasıyla ilgili yığın izleme)
Belleğin serbest bırakıldığı yerin yığın izlemesi. Yalnızca serbest bırakıldıktan sonra kullanma veya geçersiz serbest bırakma hataları için gösterilir. Sembol oluşturmak için Sembolleştirme bölümüne bakın.
Ayırma yığını izleme
Belleğin ayrıldığı yerin yığın izlemesi. Sembol oluşturmak için Sembolleştirme bölümüne bakın.
Gelişmiş hata ayıklama bilgileri
HWASan raporunda, sırasıyla aşağıdakiler de dahil olmak üzere bazı gelişmiş hata ayıklama bilgileri de yer alır:
- İşlemdeki iş parçacıklarının listesi
- İşlemdeki iş parçacıklarının listesi
- Hatalı belleğin yakınındaki bellek etiketlerinin değeri
- Belleğe erişim noktasındaki kayıtların dökümü
Bellek etiketi dökümü
İşaretçi etiketiyle aynı etikete sahip yakındaki bellek ayırmalarını aramak için etiket bellek dökümünü kullanabilirsiniz. Bu etiketler, büyük bir ofsetle sınırların dışında bir erişimi işaret edebilir. Bir etiket, 16 baytlık belleğe karşılık gelir. İşaretçi etiketi, adresin en üstteki 8 bitidir. Etiket bellek dökümü ipuçları verebilir. Örneğin, aşağıda sağa doğru bir arabellek taşması gösterilmektedir:
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 .. .. .. .. .. .. .. .. .. .. .. .. .. ..
İşaretçi etiketiyle eşleşen soldaki 6 × 16 = 96 baytlık ad etiketleri dizisini not alın.
Bir tahsisin boyutu 16'nın katı değilse boyutun kalanı bellek etiketi olarak depolanır ve etiket kısa granül etiketi olarak depolanır. Önceki örnekte, kalın yazılmış ayırma etiketinden ad hemen sonra, 5c etiketinin 5 × 16 + 4 = 84 baytlık bir ayırması vardır.
Sıfır bellek etiketi (örneğin, tags: ad/00 (ptr/mem)), stack-use-after-return hatası 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 talimata karşılık gelir. Bu dökümü, normal Android sinyal işleyicisinden alınan başka bir kayıt dökümü izler. HWASan, abort() işlevini çağırdığında alındığı için ikinci dökümü yoksayın. Bu döküm, hatayla ilgili değildir.
Simgeselleştirme
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ışı sembolleştirme adımı gerekir.
İlk kurulum: llvm-symbolizer'ı yükleyin
Sembol oluşturmak için sisteminizde llvm-symbolizer yüklü olmalı ve $PATH adresinden erişilebilir olmalıdır. Debian'da sudo apt install llvm komutunu kullanarak yükleyebilirsiniz.
Sembol dosyalarını edinme
Sembolleştirme için sembol içeren, kaldırılmamış ikili dosyalar gerekir. Konumları, derlemenin türüne bağlıdır:
- Yerel derlemeler için sembol dosyaları
out/target/product/<product>/symbols/konumundadır. - AOSP derlemeleri (ör. Android Flash Tool'dan yüklenenler) Android CI'da bulunur. Derlemeyle ilgili Artifacts (Yapılar) bölümünde bir
${PRODUCT}-symbols-${BUILDID}.zipdosyası bulunur. - Kuruluşunuzun dahili derlemeleri için sembol dosyalarını edinme konusunda yardım almak üzere kuruluşunuzun belgelerine bakın.
Simgelendirme
hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Yığın raporlarını anlama
Yığın değişkenleriyle oluşan hatalar için HWASan raporunda şu gibi ayrıntılar yer alır:
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) [...]
HWASan, yığın hatalarını anlamanıza yardımcı olmak için geçmiş yığın çerçevelerini takip eder. HWASan, bunları hata raporunda insan tarafından anlaşılabilir içeriğe dönüştürmez ve ek bir sembolleştirme adımı gerektirir.
ODR ihlalleri
HWASan tarafından bildirilen bazı "kullanımdan sonra serbest bırakma" hataları, Tek Tanımlama Kuralı (ODR) ihlalini gösterebilir. Aynı değişken aynı programda birden fazla kez tanımlandığında ODR ihlali gerçekleşir. Bu durum, değişkenin birden fazla kez yok edildiği anlamına da gelir. Bu da use-after-free hatasına yol açabilir.
Sembolleştirme işleminden sonra, ODR ihlalleri hem geçersiz erişim yığınında hem de burada serbest bırakılan yığında __cxa_finalize ile birlikte use-after-free hatası gösterir. Daha önce burada ayrılan yığın __dl__ZN6soinfo17call_constructorsEv içeriyor ve yığındaki değişkeni daha yukarıda tanımlayan programınızdaki konuma işaret etmelidir.
Statik kitaplıklar kullanılıyorsa ODR ihlal edilebilir. Bir C++ global'i tanımlayan statik bir kitaplık birden fazla paylaşılan kitaplığa veya yürütülebilir dosyaya bağlanırsa aynı sembolün birden fazla tanımı aynı adres alanında bulunabilir ve bu da ODR hatasına neden olur.
Sorun giderme
Bu bölümde bazı hatalar ve bunların nasıl giderileceği açıklanmaktadır.
HWAddressSanitizer, adresi daha ayrıntılı açıklayamıyor
HWASan bazen geçmiş bellek ayırmalarıyla ilgili bilgiler için yer kalmayabilir. Bu durumda raporda, doğrudan bellek erişimi için yalnızca bir yığın izleme (stack trace) bulunur ve ardından bir not yer alır:
HWAddressSanitizer can not describe address in more detail.
Bazı durumlarda, testi birden çok kez çalıştırarak bu sorunu çözebilirsiniz. Diğer bir seçenek de HWASan geçmiş boyutunu artırmaktır. Bunu build/soong/cc/sanitize.go bölümünde genel olarak yapabilirsiniz (hwasanGlobalOptions seçeneğini bulun) veya işlem ortamınızda yapabilirsiniz (mevcut ayarları görmek için adb shell echo $HWASAN_OPTIONS komutunu deneyin).
Bu hata, erişilen bellek eşlenmemişse veya HWASan'dan haberdar olmayan bir ayırıcı tarafından ayrılmışsa da oluşabilir. Bu durumda, kilitlenme üstbilgisinde listelenen mem etiketi genellikle 00 olur. Tam mezar taşına erişiminiz varsa adresin hangi eşlemeye (varsa) ait olduğunu öğrenmek için bellek haritaları dökümüne bakmak faydalı olabilir.
Aynı ileti dizisinde iç içe yerleştirilmiş hata
Bu, HWASan kilitlenme raporu oluşturulurken bir hata oluştuğu anlamına gelir. Bu durum genellikle HWASan çalışma zamanındaki bir hatadan kaynaklanır. Hata bildirin ve mümkünse sorunun nasıl yeniden oluşturulacağına dair talimatlar verin.