HWASan raporlarını anlama

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: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … 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ü (READ ve WRITE)
  • 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:

  1. İşlemdeki iş parçacıklarının listesi
  2. İşlemdeki iş parçacıklarının listesi
  3. Hatalı belleğin yakınındaki bellek etiketlerinin değeri
  4. 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}.zip dosyası 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.