HWASan raporlarını anlama

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

[...]

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








[ … 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:

  1. Süreçteki iş parçacıklarının listesi
  2. Süreçteki iş parçacıklarının listesi
  3. Arızalı hafızanın yakınındaki hafıza etiketlerinin değeri
  4. 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.