Memahami laporan HWASan

Ketika alat HWASan mendeteksi bug memori, proses dihentikan dengan abort(), dan laporan dicetak ke stderr dan logcat. Seperti semua kerusakan asli di Android, kesalahan HWASan dapat ditemukan di /data/tombstones .

Dibandingkan dengan error asli biasa, HWASan membawa informasi tambahan di bidang “Batalkan pesan” di dekat bagian atas batu nisan. Lihat contoh kerusakan berbasis heap di bawah (untuk bug tumpukan, lihat catatan di bawah untuk bagian khusus tumpukan).

Contoh laporan

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
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 …]

Ini sangat mirip dengan laporan AddressSanitizer . Berbeda dengan itu, hampir semua bug HWASan adalah “tag-mismatch”, yaitu akses memori dimana tag pointer tidak cocok dengan tag memori yang bersangkutan. Ini bisa jadi salah satunya

  • akses di luar batas pada tumpukan atau heap
  • gunakan setelah gratis di heap
  • gunakan setelah kembali ke tumpukan

Bagian

Penjelasan masing-masing bagian laporan HWASan adalah sebagai berikut:

Kesalahan Akses

Berisi informasi mengenai akses memori yang buruk, antara lain:

  • Jenis Akses ("BACA" vs. "TULIS")
  • Ukuran akses (berapa byte yang dicoba diakses)
  • Nomor thread akses
  • Tag penunjuk dan memori (untuk proses debug tingkat lanjut)

Akses Pelacakan Tumpukan

Jejak tumpukan akses memori yang buruk. Lihat bagian Simbolisasi untuk melambangkan.

Menyebabkan

Potensi penyebab buruknya akses. Jika ada beberapa kandidat, mereka diurutkan berdasarkan kemungkinannya. Mengawali informasi rinci tentang penyebab potensial. HWASan dapat mendiagnosis penyebab berikut:

  • gunakan setelah bebas
  • tumpukan tag-ketidakcocokan: ini dapat berupa tumpukan penggunaan-setelah-pengembalian/penggunaan setelah-lingkup, atau di luar batas
  • tumpukan-buffer-overflow
  • luapan global

Informasi Memori

Menjelaskan apa yang HWASan ketahui tentang memori yang sedang diakses, dan mungkin berbeda berdasarkan jenis bug.

Jenis Bug Menyebabkan Format Laporan
ketidakcocokan tag gunakan setelah bebas
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
tumpukan-buffer-overflow Perhatikan bahwa ini juga bisa menjadi arus bawah.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
  allocated here:
tumpukan tag-ketidakcocokan Laporan tumpukan tidak membedakan antara bug overflow/underflow dan use-after-return bug. Selain itu, untuk menemukan alokasi tumpukan yang menjadi sumber kesalahan, diperlukan langkah simbolisasi offline. Lihat bagian Memahami laporan tumpukan di bawah.
bebas tidak valid gunakan setelah bebas Ini adalah bug gratis ganda. Jika hal ini terjadi pada proses penghentian, hal ini dapat menandakan pelanggaran ODR .
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
tidak dapat menjelaskan alamatnya Entah bebas liar (bebas dari memori yang belum pernah dialokasikan sebelumnya), atau bebas ganda setelah memori yang dialokasikan dikeluarkan dari buffer gratis HWASan.
0x… adalah memori bayangan HWAsan. Ini benar-benar gratis, karena aplikasi mencoba mengosongkan memori internal HWASan.

Pelacakan Tumpukan Dealokasi

Jejak tumpukan di mana memori tidak dialokasikan. Hanya hadir untuk bug yang digunakan setelah bebas atau tidak valid. Lihat bagian Simbolisasi untuk melambangkan.

Pelacakan Tumpukan Alokasi

Jejak tumpukan di mana memori dialokasikan. Lihat bagian Simbolisasi untuk melambangkan.

Informasi Debugging Tingkat Lanjut

Laporan HWASan juga menampilkan beberapa informasi proses debug tingkat lanjut, termasuk (secara berurutan):

  1. Daftar thread dalam proses
  2. Daftar thread dalam proses
  3. Nilai tag memori di dekat memori yang rusak
  4. Pembuangan register pada titik akses memori

Pembuangan Tag Memori

Tag memory dump dapat digunakan untuk mencari alokasi memori terdekat dengan tag yang sama dengan tag pointer. Hal ini dapat menunjukkan adanya akses di luar batas dengan offset yang besar. Satu tag setara dengan 16 byte memori; tag penunjuk adalah 8 bit teratas dari alamat. Tag memory dump dapat memberikan petunjuk, misalnya berikut ini adalah buffer overflow di sebelah kanan:

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  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
(perhatikan rangkaian 6 × 16 = 96 byte tag “iklan” di sebelah kiri yang cocok dengan tag penunjuk).

Jika ukuran alokasi bukan kelipatan 16, sisa ukurannya akan disimpan sebagai tag memori dan tag tersebut akan disimpan sebagai tag butiran pendek . Pada contoh di atas tepat setelah alokasi tag iklan yang dicetak tebal, kita memiliki alokasi tag 5c 5 × 16 + 4 = 84 byte.

Tag memori nol (mis. tags: ad/ 00 (ptr/mem) ) biasanya menunjukkan bug penggunaan tumpukan setelah pengembalian.

Daftarkan Pembuangan

Register dump dalam laporan HWASan sesuai dengan instruksi sebenarnya yang melakukan akses memori tidak valid. Hal ini diikuti oleh register dump lain dari pengendali sinyal Android biasa - abaikan yang kedua , ini diambil ketika HWASan memanggil abort() dan tidak relevan dengan bug.

Simbolisasi

Untuk mendapatkan nama fungsi dan nomor baris dalam pelacakan tumpukan (dan mendapatkan nama variabel untuk bug penggunaan setelah cakupan), diperlukan langkah simbolisasi offline.

Penyiapan pertama kali: instal llvm-ymbolizer

Untuk melambangkan, sistem Anda harus menginstal llvm-symbolizer dan dapat diakses dari $PATH. Di Debian, Anda dapat menginstalnya menggunakan sudo apt install llvm .

Dapatkan file simbol

Untuk simbolisasi, kita memerlukan biner tak terlucuti yang berisi simbol. Lokasinya bergantung pada jenis bangunan:

Untuk build lokal , file simbol dapat ditemukan di out/target/product/<product>/symbols/ .

Untuk build AOSP (misalnya, di-flash dari Flashstation ), build tersebut dapat ditemukan di Android CI . Di "Artefak" untuk build, akan ada file `${product}-symbols-${BUILDID}.zip`.

Untuk build internal dari organisasi Anda, periksa dokumentasi organisasi Anda untuk mendapatkan bantuan dalam mendapatkan file simbol.

Melambangkan

hwasan_symbolize –-symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

Memahami Laporan Tumpukan

Untuk bug yang terjadi pada variabel stack, laporan HWASan akan berisi detail seperti ini:

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)
  [...]
	

Agar bug tumpukan dapat dipahami, HWASan melacak frame tumpukan yang terjadi di masa lalu. Saat ini, HWASan tidak mengubahnya menjadi konten yang dapat dipahami manusia dalam laporan bug, dan memerlukan langkah simbolisasi tambahan.

Pelanggaran ODR

Beberapa bug penggunaan setelah bebas yang dilaporkan oleh HWASan juga dapat mengindikasikan pelanggaran Aturan Satu Definisi (ODR). Pelanggaran ODR terjadi ketika variabel yang sama didefinisikan beberapa kali dalam program yang sama. Ini juga berarti bahwa variabel tersebut dihancurkan beberapa kali, yang dapat menyebabkan kesalahan penggunaan setelah bebas.

Setelah simbolisasi, pelanggaran ODR menunjukkan penggunaan setelah bebas dengan __cxa_finalize , pada tumpukan akses yang tidak valid dan tumpukan "dibebaskan di sini". Tumpukan "yang sebelumnya dialokasikan di sini" berisi __dl__ZN6soinfo17call_constructorsEv dan harus menunjuk ke lokasi di program Anda yang mendefinisikan variabel yang lebih tinggi di tumpukan.

Salah satu alasan mengapa ODR dapat dilanggar adalah ketika perpustakaan statis digunakan. Jika pustaka statis yang mendefinisikan global C++ ditautkan ke beberapa pustaka bersama atau executable, beberapa definisi dari simbol yang sama mungkin akan ada di ruang alamat yang sama, yang akan menyebabkan kesalahan ODR.

Penyelesaian masalah

"HWAddressSanitizer tidak dapat menjelaskan alamat secara lebih detail."

Terkadang HWASan kehabisan ruang untuk informasi tentang alokasi memori masa lalu. Dalam hal ini, laporan hanya akan berisi satu pelacakan tumpukan untuk akses memori langsung, diikuti dengan catatan:

  HWAddressSanitizer can not describe address in more detail.

Dalam beberapa kasus, hal ini dapat diatasi dengan menjalankan pengujian beberapa kali. Pilihan lainnya adalah meningkatkan ukuran riwayat HWASan. Ini dapat dilakukan secara global di build/soong/cc/sanitize.go (cari hwasanGlobalOptions ), atau di lingkungan proses Anda (coba adb shell echo $HWASAN_OPTIONS untuk melihat pengaturan saat ini).

Hal ini juga dapat terjadi jika memori yang diakses tidak dipetakan, atau dialokasikan oleh pengalokasi non-HWASan. Dalam hal ini, tag mem yang tercantum di header kerusakan biasanya adalah 00 . Jika Anda memiliki akses ke batu nisan lengkap, mungkin ada baiknya untuk memeriksa dump peta memori untuk mengetahui pemetaan mana (jika ada) yang dimiliki oleh alamat tersebut.

"bug bersarang di thread yang sama"

Ini berarti ada bug saat membuat laporan kerusakan HWASan. Hal ini biasanya disebabkan oleh bug pada runtime HWASan, harap laporkan bug dan berikan instruksi tentang cara mereproduksi masalah tersebut jika memungkinkan.