Memahami laporan HWASan

Saat alat HWASan mendeteksi bug memori, proses akan dihentikan dengan abort(), dan laporan akan dicetak ke stderr dan logcat. Seperti semua error native di Android, error HWASan berada di /data/tombstones.

Contoh laporan

Dibandingkan dengan error native reguler, HWASan membawa informasi tambahan di kolom Pesan penghentian di dekat bagian atas tombstone. Berikut adalah contoh error berbasis heap. Untuk bug stack, lihat catatan untuk bagian khusus stack.

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

Hal ini mirip dengan laporan AddressSanitizer. Tidak seperti itu, hampir semua bug HWASan adalah error ketidakcocokan tag, yaitu akses memori dengan tag pointer yang tidak cocok dengan tag memori yang sesuai. Hal ini dapat berupa salah satu dari hal berikut:

  • Akses di luar batas pada stack atau heap
  • Error use-after-free pada heap
  • Error penggunaan setelah ditampilkan di stack

Bagian

Berikut adalah penjelasan setiap bagian laporan HWASan.

Error akses

Berisi informasi tentang akses memori yang buruk, termasuk:

  • Jenis akses (READ versus WRITE)
  • Ukuran akses (jumlah byte yang dicoba diakses)
  • Nomor thread akses
  • Tag pointer dan memori (untuk proses debug lanjutan)

Mengakses pelacakan tumpukan

Stack trace dari akses memori yang buruk. Lihat Simbolisasi untuk memberi simbol.

Penyebab

Potensi penyebab akses yang buruk. Jika ada beberapa kandidat, kandidat tersebut akan dicantumkan dalam urutan kemungkinan menurun. Mendahului info mendetail tentang potensi penyebabnya. HWASan dapat mendiagnosis penyebab berikut:

  • Penggunaan setelah tersedia
  • Ketidakcocokan tag stack, yang dapat berupa penggunaan stack setelah ditampilkan, penggunaan stack setelah cakupan, atau di luar batas
  • Overflow buffer heap
  • Overflow global

Informasi memori

Menjelaskan apa yang diketahui HWASan tentang memori yang diakses, dan dapat berbeda berdasarkan jenis bug:

Jenis bug Penyebab Format laporan
Ketidakcocokan tag Penggunaan setelah tersedia Gunakan format laporan ini:
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Overflow buffer heap Perhatikan bahwa ini juga dapat berupa underflow.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
allocated here:
Ketidakcocokan tag stack Laporan stack tidak membedakan antara overflow atau underflow dan bug penggunaan setelah pengembalian. Selain itu, untuk menemukan alokasi stack yang merupakan sumber error, langkah simbolisasi offline diperlukan. Lihat Memahami laporan stack.
Gratis tidak valid Penggunaan setelah tersedia Bug double free. Jika hal ini terjadi saat proses dimatikan, 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 mendeskripsikan alamat Baik free liar (bebas dari memori yang belum dialokasikan sebelumnya), atau free ganda setelah memori yang dialokasikan dihapus dari buffer bebas HWASan.
0x... adalah memori bayangan HWAsan Free liar, karena aplikasi mencoba mengosongkan memori yang bersifat internal untuk HWASan.

Pelacakan tumpukan dealokasi

Stack trace tempat memori didealokasikan. Hanya ada untuk bug use-after-free atau invalid-free. Lihat Simbolisasi untuk membuat simbol.

Pelacakan tumpukan alokasi

Stack trace tempat memori dialokasikan. Lihat Simbolisasi untuk membuat simbol.

Informasi proses debug lanjutan

Laporan HWASan juga menampilkan beberapa informasi proses debug lanjutan, termasuk (berurutan):

  1. Daftar thread dalam proses
  2. Daftar thread dalam proses
  3. Nilai tag memori di dekat memori yang mengalami error
  4. Dump register pada titik akses memori

Memory tag dump

Anda dapat menggunakan dump memori tag untuk mencari alokasi memori di sekitar dengan tag yang sama seperti tag pointer. Tag ini dapat mengarah ke akses di luar batas dengan offset yang besar. Satu tag sesuai dengan 16 byte memori; tag pointer adalah 8 bit teratas dari alamat. Dump memori tag dapat memberikan petunjuk, misalnya, berikut adalah overflow buffer 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 operasi 6 × 16 = 96 byte tag ad di sebelah kiri yang cocok dengan tag pointer.

Jika ukuran alokasi bukan kelipatan 16, sisa ukuran akan disimpan sebagai tag memori dan tag disimpan sebagai tag granul pendek. Pada contoh sebelumnya, tepat setelah alokasi tebal yang diberi tag ad, kita memiliki alokasi tag 5c sebesar 5 × 16 + 4 = 84 byte.

Tag memori nol (misalnya, tags: ad/00 (ptr/mem)) menunjukkan bug stack-use-after-return.

Dump register

Dump register dalam laporan HWASan sesuai dengan petunjuk yang melakukan akses memori yang tidak valid. Dump ini diikuti dengan dump register lain dari pengendali sinyal Android reguler. Abaikan dump kedua, karena diambil saat 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), langkah simbolisasi offline diperlukan.

Penyiapan pertama kali: menginstal llvm-symbolizer

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

Mendapatkan file simbol

Untuk simbolisasi, kami memerlukan biner yang tidak dihapus yang berisi simbol. Lokasinya bergantung pada jenis build:

  • Untuk build lokal, file simbol berada di out/target/product/<product>/symbols/.
  • Untuk build AOSP (misalnya, di-flash dari Android Flash Tool), build tersebut ada di Android CI. Di Artefak untuk build, ada file ${PRODUCT}-symbols-${BUILDID}.zip.
  • Untuk build internal dari organisasi Anda, periksa dokumentasi organisasi untuk mendapatkan bantuan dalam mendapatkan file simbol.

Menyimbolkan

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

Memahami laporan stack

Untuk bug yang terjadi dengan variabel stack, laporan HWASan 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)
  [...]

Untuk membantu Anda memahami bug stack, HWASan melacak frame stack sebelumnya. HWASan tidak mengubahnya menjadi konten yang dapat dipahami manusia dalam laporan bug, dan memerlukan langkah simbolisasi tambahan.

Pelanggaran ODR

Beberapa bug use-after-free yang dilaporkan oleh HWASan dapat menunjukkan pelanggaran One Definition Rule (ODR). Pelanggaran ODR terjadi saat variabel yang sama ditentukan beberapa kali dalam program yang sama. Hal ini juga berarti bahwa variabel dihancurkan beberapa kali, yang dapat menyebabkan error use-after-free.

Setelah simbolisasi, pelanggaran ODR menampilkan error use-after-free dengan __cxa_finalize, pada stack akses yang tidak valid dan stack dibebaskan di sini. Stack yang sebelumnya dialokasikan di sini berisi __dl__ZN6soinfo17call_constructorsEv dan harus menunjuk ke lokasi dalam program Anda yang menentukan variabel yang lebih tinggi di stack.

ODR dapat dilanggar jika library statis digunakan. Jika library statis yang menentukan global C++ ditautkan ke beberapa library bersama atau file yang dapat dieksekusi, beberapa definisi simbol yang sama mungkin ada di ruang alamat yang sama, yang menyebabkan error ODR.

Pemecahan masalah

Bagian ini menjelaskan beberapa error dan cara mengatasinya.

HWAddressSanitizer tidak dapat menjelaskan alamat secara lebih mendetail

Terkadang HWASan dapat kehabisan ruang untuk informasi tentang alokasi memori sebelumnya. Dalam hal tersebut, laporan hanya berisi satu pelacakan tumpukan untuk akses memori langsung, diikuti dengan catatan:

HWAddressSanitizer can not describe address in more detail.

Dalam beberapa kasus, Anda dapat mengatasinya dengan menjalankan pengujian beberapa kali. Opsi lainnya adalah meningkatkan ukuran histori HWASan. Anda dapat melakukannya secara global di build/soong/cc/sanitize.go (cari hwasanGlobalOptions), atau di lingkungan proses (coba adb shell echo $HWASAN_OPTIONS untuk melihat setelan saat ini).

Error ini juga dapat terjadi jika memori yang diakses tidak dipetakan, atau dialokasikan oleh alokator yang tidak mengetahui HWASan. Dalam hal ini, tag mem yang tercantum di header error umumnya 00. Jika Anda memiliki akses ke tombstone lengkap, sebaiknya lihat dump peta memori untuk mengetahui pemetaan mana (jika ada) yang dimiliki alamat.

Bug bertingkat dalam rangkaian pesan yang sama

Artinya, ada bug saat membuat laporan error HWASan. Hal ini biasanya disebabkan oleh bug dalam runtime HWASan. Laporkan bug dan berikan petunjuk cara merekonstruksi masalah jika memungkinkan.