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ındadır.
Örnek rapor
Normal yerel kilitlenmelere kıyasla HWASan, kilitlenme mesajının üst kısmındaki İptal mesajı alanında ek bilgiler içerir. Aşağıda, yığına dayalı bir kilitlenme örneği verilmiştir. Grupla ilgili hatalar için gruplara özel bölümlerdeki notu inceleyin.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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, HWASan hatalarının neredeyse tamamı etiket uyuşmazlığı hatasıdır. Yani, işaretçi etiketinin ilgili bellek etiketiyle eşleşmediği bir bellek erişimidir. Bu, aşağıdakilerden herhangi biri olabilir:
- Yığın veya yığınta sınırların dışında erişim
- Yığınta serbest bırakmadan sonra kullanma hatası
- Yığınta döndükten sonra kullanma hatası
Bölümler
HWASan raporunun her bir bölümünün açıklaması aşağıda verilmiştir.
Erişim hatası
Aşağıdakiler dahil olmak üzere hatalı bellek erişimi hakkında bilgi içerir:
- Erişim türü (
READ
veWRITE
) - Erişim boyutu (erişim denemesi yapılan bayt sayısı)
- 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. Simgelemek için Simgeleme bölümüne bakın.
Neden
Kötü erişimin olası nedeni. Birden fazla aday varsa bunlar olasılık azalan sırayla listelenir. Olası nedenle ilgili ayrıntılı bilgilerden önce gelir. HWASan aşağıdaki nedenleri teşhis edebilir:
- Ücretsiz kullanımdan sonra
- Döndürme sonrası yığın kullanımı, kapsam sonrası yığın kullanımı veya sınırların dışında olma gibi yığın etiketi uyuşmazlığı
- Yığın arabelleği taşması
- Küresel taşma
Bellek bilgileri
HWASan'ın erişilen bellek hakkında bildiği bilgileri 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 arabelleği taşması | Bunun bir alt taşma olabileceğini de unutmayın.<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
|
Grup etiketi uyuşmazlığı | Yığın raporları, taşma veya eksik aksama ile döndükten sonra kullanma hataları arasında ayrım yapmaz. Ayrıca, hatanın kaynağı olan yığın tahsisini bulmak için çevrimdışı bir sembolleştirme adımı gerekir. Gruptaki raporları anlama başlıklı makaleyi inceleyin. | |
Geçersiz ücretsiz | Ücretsiz kullanımdan sonra | Çift serbest bırakma hatası. Bu durum, işlem kapatıldığında gerçekleşirse ODR ihlaline işaret edebilir.
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
Adres açıklanamıyor | Ya rastgele bir serbest bırakma (daha önce ayrılmamış bellek) ya da ayrılan bellek HWASan'ın boş arabelleğinden çıkarıldıktan sonra çift serbest bırakma. | |
0x..., HWAsan gölge belleğidir. | Uygulama, HWASan'a ait belleği boşaltmaya çalıştığı için rastgele bir boşaltma işlemi. |
Yer tahsis etme yığın izleme
Belleğin tahsisinden kaldırıldığı yığın izleme. Yalnızca ücretsiz kullanımdan sonra veya geçersiz ücretsiz kullanımla ilgili hatalar için gösterilir. Simgelemek için Simgeleme bölümüne bakın.
Ayırma yığın izleme
Belleğin tahsis edildiği yığın izleme. Simgelemek için Simgeleme bölümüne bakın.
Gelişmiş hata ayıklama bilgileri
HWASan raporunda, 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
- Hata veren belleğin yakınındaki bellek etiketlerinin değeri
- Bellek erişimi noktasındaki kaydedici dökümü
Bellek etiketi dökümü
İşaretçi etiketiyle aynı etikete sahip yakın bellek tahsislerini aramak için etiket bellek dökümü'nü kullanabilirsiniz. Bu etiketler, büyük bir ofset içeren, sınırların dışındaki bir erişimi işaret edebilir. Bir etiket 16 bayt belleğe karşılık gelir. İşaretçi etiketi, adresin en üstteki 8 bitini ifade eder. Etiket bellek dökümü ipucu verebilir. Örneğin, aşağıdaki sağ taraftaki bir 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 .. .. .. .. .. .. .. .. .. .. .. .. .. ..
İşaretçi etiketiyle eşleşen 6 × 16 = 96 baytlık ad
etiketi dizisine dikkat edin.
Bir ayırmanın boyutu 16'nın katı değilse boyutun kalanı bellek etiketi olarak, etiket ise kısa granül etiketi olarak depolanır. Önceki örnekte, kalın harflerle yazılmış ad
etiketli ayırmanın hemen ardından 5 × 16 + 4 = 84 baytlık bir 5c
etiketi ayırması vardır.
Sıfır bellek etiketi (örneğin, tags: ad/00 (ptr/mem)
), döndükten sonra yığın kullanımıyla ilgili bir hatayı 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ün ardından, normal Android sinyal işleyicisinden alınan başka bir kayıt dökümü gelir. HWASan abort()
çağrılırken alındığı ve hatayla alakalı olmadığı için ikinci döküm dosyasını yoksayın.
Simgeleştirme
Yığın izlemelerinde işlev adlarını ve satır numaralarını almak (ve kapsamdan sonra kullanma hatalarıyla ilgili değişken adlarını almak) için çevrimdışı bir sembolleştirme adımı gerekir.
İlk kurulum: llvm-symbolizer'ı yükleyin
Bu simge, sisteminizin llvm-symbolizer
yüklü ve $PATH
'ten erişilebilir olması gerektiği anlamına gelir. Debian'da sudo apt install llvm
kullanarak yükleyebilirsiniz.
Simge dosyalarını edinme
Semboller için, sembol içeren ve sarmalayıcısı kaldırılmış ikili dosyalar gerekir. Bu dosyaların konumu derleme türüne bağlıdır:
- Yerel derlemeler için simge dosyaları
out/target/product/<product>/symbols/
içindedir. - AOSP derlemeleri (ör. Android Flash Aracı ile yüklenen) Android CI'de bulunur. Derleme için Öğeler bölümünde bir
${PRODUCT}-symbols-${BUILDID}.zip
dosyası vardır. - Kuruluşunuzun dahili derlemeleri için simge dosyalarını edinme konusunda yardım almak üzere kuruluşunuzun dokümanlarını inceleyin.
Simgeleştirme
hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash
Grup raporlarını anlama
Yığın değişkenleriyle ilgili hatalar için HWASan raporunda aşağıdaki 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 izler. HWASan, bunları hata raporunda kullanıcıların anlayabileceği bir içeriğe dönüştürmez ve ek bir sembolleştirme adımı gerektirir.
ODR ihlalleri
HWASan tarafından bildirilen bazı ücretsiz kullanım sonrası hatalar, Tek Tanım Kuralı'nın (ODR) ihlal edildiğini gösterebilir. Aynı değişken aynı programda birden çok kez tanımlandığında ODR ihlali meydana gelir. Bu durum, değişkenin birden fazla kez imha edildiği anlamına da gelir. Bu da, serbest bırakıldıktan sonra kullanma hatasına neden olabilir.
Simgeleştirmeden sonra ODR ihlalleri, hem geçersiz erişim yığınında hem de buradan serbest bırakıldı yığınında __cxa_finalize
ile ilgili bir serbest bırakıldıktan sonra kullanma hatası gösterir. Daha önce burada ayrılmış yığın __dl__ZN6soinfo17call_constructorsEv
içerir ve programınızdaki yığının üst kısmında değişkeni tanımlayan konumu işaret etmelidir.
Statik kitaplıklar kullanılırsa ODR ihlal edilebilir. C++ genel tanımını yapan statik bir kitaplık birden fazla paylaşılan kitaplığa veya yürütülebilir dosyaya bağlanırsa aynı adres alanında aynı sembolün birden fazla tanımı olabilir. Bu da ODR hatasına neden olur.
Sorun giderme
Bu bölümde bazı hatalar ve bunların nasıl ele alınacağı açıklanmaktadır.
HWAddressSanitizer, adresi daha ayrıntılı şekilde açıklayamıyor
Bazen HWASan'da geçmiş bellek tahsisleriyle ilgili bilgiler için yer kalmayabilir. Bu durumda rapor, anlık bellek erişimi için yalnızca bir yığın izleme ve ardından bir not içerir:
HWAddressSanitizer can not describe address in more detail.
Bazı durumlarda, testi birden çok kez çalıştırarak bu sorunu çözebilirsiniz. Başka bir seçenek de HWASan geçmişi boyutunu artırmaktır. Bunu build/soong/cc/sanitize.go
'te (hwasanGlobalOptions
'u arayın) veya işlem ortamınızda (mevcut ayarları görmek için adb shell echo $HWASAN_OPTIONS
'yi deneyin) global olarak yapabilirsiniz.
Bu hata, erişilen bellek eşlenmemişse veya HWASan farkında olmayan bir ayırıcı tarafından ayrılmışsa da ortaya çıkabilir. Bu durumda, kilitlenme üstbilgisinde listelenen mem
etiketi genellikle 00
olur. Tam mezar taşı erişiminiz varsa adresin hangi eşlemeye (varsa) ait olduğunu öğrenmek için bellek haritaları dökümüne bakmanız faydalı olabilir.
Aynı ileti dizisinde iç içe yerleştirilmiş hata
Bu, HWASan kilitlenme raporu oluşturulurken bir hata olduğu anlamına gelir. Bu durum genellikle HWASan çalışma zamanındaki bir hatadan kaynaklanır. Hata kaydı gönderin ve mümkünse sorunun nasıl yeniden oluşturulacağına dair talimatlar sağlayın.