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 bawah /data/tombstones.

Contoh laporan

Dibandingkan dengan error native biasa, HWASan membawa informasi tambahan di kolom Pesan pembatalan di dekat bagian atas penanda. 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 saat tag penunjuk tidak cocok dengan tag memori yang sesuai. Ini bisa berupa salah satu dari berikut ini:

  • Akses di luar batas pada stack atau heap
  • Error penggunaan setelah pelepasan pada heap
  • Error penggunaan setelah ditampilkan pada stack

Bagian

Berikut penjelasan setiap bagian laporan HWASan.

Error akses

Berisi informasi tentang akses memori yang buruk, termasuk:

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

Mengakses pelacakan tumpukan

Stack trace akses memori yang buruk. Lihat Simbolisasi untuk mensimbolkan.

Penyebab

Kemungkinan penyebab akses yang buruk. Jika ada beberapa kandidat, kandidat tersebut dicantumkan dalam urutan kemungkinan menurun. Mendahului info mendetail tentang kemungkinan penyebab. 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
  • Heap buffer overflow
  • Tambahan global

Informasi memori

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

Jenis bug Penyebab Format laporan
Tag tidak cocok Penggunaan setelah tersedia Gunakan format laporan ini:
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Heap buffer overflow Perhatikan bahwa hal 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 use-after-return. Selain itu, untuk menemukan alokasi stack yang menjadi sumber error, diperlukan langkah simbolisasi offline. Lihat Memahami laporan stack.
Gratis tidak valid Penggunaan setelah tersedia Bug double free. Jika hal ini terjadi saat penonaktifan proses, 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 wild free (memori bebas yang belum dialokasikan sebelumnya), atau double free setelah memori yang dialokasikan dikeluarkan dari buffer bebas HWASan.
0x... adalah memori bayangan HWASan Pelepasan memori yang tidak terkendali, karena aplikasi mencoba melepaskan memori yang bersifat internal untuk HWASan.

Stack trace pelepasan alokasi

Stack trace tempat memori dibebaskan. Hanya ada untuk bug penggunaan setelah gratis atau tidak valid gratis. Lihat Simbolisasi untuk menyimbolkan.

Pelacakan tumpukan alokasi

Stack trace tempat memori dialokasikan. Lihat Simbolisasi untuk menyimbolkan.

Informasi proses debug lanjutan

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

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

Dump tag memori

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

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

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

Register dump

Dump register dalam laporan HWASan sesuai dengan instruksi yang melakukan akses memori tidak valid. Dump ini diikuti oleh dump register lain dari handler 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), diperlukan langkah simbolisasi offline.

Penyiapan pertama kali: instal llvm-symbolizer

Untuk menyimbolkan, 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 di-strip 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 Anda untuk mendapatkan bantuan dalam memperoleh file simbol.

Melambangkan

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 Aturan Satu Definisi (ODR). Pelanggaran ODR terjadi saat variabel yang sama ditentukan beberapa kali dalam program yang sama. Artinya juga variabel dihancurkan beberapa kali, yang dapat menyebabkan error use-after-free.

Setelah simbolisasi, pelanggaran ODR menunjukkan error use-after-free dengan __cxa_finalize, pada stack akses tidak valid dan stack freed here. Stack previously allocated here berisi __dl__ZN6soinfo17call_constructorsEv dan harus menunjuk ke lokasi dalam program Anda yang menentukan variabel lebih tinggi di stack.

ODR dapat dilanggar jika library statis digunakan. Jika library statis yang menentukan global C++ ditautkan ke beberapa library atau 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 ini, laporan hanya berisi satu rekaman aktivitas stack untuk akses memori langsung, diikuti dengan catatan:

HWAddressSanitizer can not describe address in more detail.

Dalam beberapa kasus, Anda dapat menyelesaikannya 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 Anda (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 kompatibel dengan HWASan. Dalam hal ini, tag mem yang tercantum di header error umumnya adalah 00. Jika Anda memiliki akses ke tombstone lengkap, mungkin akan berguna untuk melihat dump peta memori guna mengetahui pemetaan (jika ada) yang dimiliki alamat tersebut.

Bug bertingkat dalam rangkaian pesan yang sama

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