Memahami laporan HWASan

Saat alat HWASan mendeteksi bug memori, proses akan dihentikan dengan abort(), dan laporan dicetak ke {i> stderr<i} dan {i>logcat<i}. Seperti semua masalah pada native code di Android, error HWASan dapat ditemukan di bawah /data/tombstones.

Dibandingkan dengan masalah pada native code reguler, HWASan membawa informasi tambahan di kolom “Batalkan pesan” di dekat bagian atas batu nisan. Lihat contoh error berbasis heap di bawah ini (untuk bug stack, lihat catatan di bawah untuk bagian khusus stack).

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

Hal ini sangat mirip dengan laporan AddressSanitizer. Tidak seperti itu, hampir semua bug HWASan memiliki "tag-mismatch", yaitu akses memori di mana tag pointer melakukan tidak cocok dengan tag memori yang sesuai. Ini bisa menjadi salah satu

  • melampaui batas akses pada stack atau heap
  • gunakan setelah kosong di heap
  • gunakan setelah return on stack

Bagian

Penjelasan dari setiap bagian laporan HWASan adalah sebagai berikut:

Error akses

Berisi informasi tentang akses memori yang buruk, termasuk:

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

Mengakses stack trace

Stack trace akses memori buruk. Lihat bagian Simbolisasi untuk melambangkan sesuatu.

Penyebab

Kemungkinan penyebab akses yang buruk. Jika ada beberapa kandidat, adalah terdaftar dengan urutan kemungkinan menurun. Mendahului info detail tentang penyebabnya. HWASan dapat mendiagnosis penyebab berikut:

  • use-after-free
  • stack tag-mismatch: dapat berupa stack use-after-return / use after-scope, atau di luar batas
  • heap-buffer-overflow
  • global-overflow

Informasi memori

Menjelaskan apa yang diketahui HWASan tentang memori yang sedang diakses, dan mungkin berbeda berdasarkan jenis {i>bug<i}.

Jenis Serangga Penyebab Format Laporan
tag tidak cocok use-after-free
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
heap-buffer-overflow 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 {i>overflow/underflow<i} dan {i>use-after-return bug<i}. Di beberapa juga, untuk menemukan alokasi tumpukan yang merupakan sumber kesalahan, offline simbolisasi diperlukan. Lihat Memahami laporan stack di bawah ini.
tidak valid use-after-free Ini adalah bug gratis ganda. Jika ini terjadi saat penonaktifan proses, ini dapat menandakan bahwa Pelanggaran ODR.
<address> is located N bytes inside of M-byte region [<start>, <end>)
  freed by thread T0 here:
tidak dapat mendeskripsikan alamat Dapat berupa {i>wildcard<i} (bebas dari memori yang belum pernah dialokasikan sebelumnya), atau bebas ganda setelah memori yang dialokasikan dikeluarkan dari {i>buffer <i}bebas HWASan.
0x... adalah memori bayangan HWAsan. Ini benar-benar gratis, karena aplikasi mencoba untuk memori yang internal ke HWASan.

Stack trace dealokasi

Stack trace tempat memori dibatalkan alokasinya. Hanya hadir untuk digunakan setelah gratis atau tidak ada bug yang tidak valid. Lihat bagian Simbolisasi untuk melambangkan.

Stack trace alokasi

Stack trace tempat memori dialokasikan. Lihat bagian Simbolisasi untuk melambangkan.

Proses debug lanjutan Informasi

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 faulting
  4. Dump register pada titik akses memori

Timbunan tag memori

Dump memori tag dapat digunakan untuk mencari alokasi memori di sekitar dengan tag yang sama sebagai kursor . Izin ini dapat menunjukkan akses di luar batas dengan offset besar. Satu tag sesuai dengan 16 byte memori; tag pointer adalah 8 bit teratas dari alamat tersebut. Dump memori tag dapat memberikan petunjuk, untuk contoh berikut ini adalah luapan 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 run 6 × 16 = 96 byte tag "ad" di sebelah kiri yang cocok dengan tag pointer).

Jika ukuran alokasi bukan kelipatan 16, ukuran sisanya adalah disimpan sebagai tag memori dan tag tersebut akan disimpan sebagai tag granule. Pada contoh di atas, tepat setelah alokasi yang dicetak tebal diberi tag iklan, kami punya 5 × 16 + 4 = 84 byte alokasi tag 5c.

Tag memori nol (mis. tags: ad/00 (ptr/mem)) biasanya menunjukkan {i>stack-use-after-return bug<i}.

Daftarkan dump

Dump register dalam laporan HWASan sesuai dengan instruksi sebenarnya yang melakukan tidak valid memori akses. Ini diikuti oleh dump register lain dari pengendali sinyal Android reguler "-" abaikan yang kedua, diambil saat HWASan memanggil abort() dan tidak relevan dengan {i>bug<i} itu.

Simbolisasi

Untuk mendapatkan nama fungsi dan nomor baris dalam stack trace (dan mendapatkan nama variabel untuk use-after-scope) {i>bug<i}), diperlukan langkah simbolisasi offline.

Penyiapan pertama kali: instal llvm-symbolizer

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

Mendapatkan file simbol

Untuk simbolisasi, kita membutuhkan biner unstripped yang berisi simbol. Tempat ditemukannya hal-hal tersebut bergantung pada jenis build:

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

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

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

Simbolkan

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

Memahami laporan stack

Untuk bug yang terjadi dengan 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 stack 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 setelah gratis yang dilaporkan oleh HWASan juga dapat menunjukkan pelanggaran One Definition Rule (ODR). Pelanggaran ODR terjadi jika variabel yang sama ditentukan beberapa kali dalam program yang sama. Ini juga berarti bahwa variabel itu dihancurkan beberapa kali, yang dapat menyebabkan {i>use-after-free<i}.

Setelah simbolisasi, pelanggaran ODR menunjukkan penggunaan setelah gratis dengan __cxa_finalize, pada stack akses yang tidak valid dan "dibebaskan di sini" {i>stack<i}. Kolom "yang dialokasikan sebelumnya di sini" stack berisi __dl__ZN6soinfo17call_constructorsEv dan seharusnya menunjuk ke lokasi dalam program Anda yang mendefinisikan variabel yang lebih tinggi dalam tumpukan.

Salah satu alasan mengapa ODR dapat dilanggar adalah ketika library statis digunakan. Jika sebuah pustaka statis yang mendefinisikan C++ global ditautkan ke dalam beberapa pustaka bersama atau {i>executable<i}, beberapa definisi dari simbol yang sama mungkin berakhir ada di alamat yang sama yang akan menyebabkan kesalahan ODR.

Pemecahan masalah

HWAddressSanitizer tidak dapat mendeskripsikan alamat secara lebih detail

Terkadang HWASan dapat kehabisan ruang untuk informasi tentang alokasi memori sebelumnya. Dalam kasus tersebut, laporan hanya akan berisi satu stack trace untuk akses memori langsung, diikuti dengan sebuah catatan:

  HWAddressSanitizer can not describe address in more detail.

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

Ini juga bisa terjadi jika memori yang diakses tidak dipetakan, atau dialokasikan oleh perangkat non-HWASan alokator. Dalam hal ini, tag mem yang tercantum di header error umumnya akan 00. Jika Anda memiliki akses ke batu nisan yang lengkap, sebaiknya lihat {i>memory dump<i} untuk mengetahui pemetaan mana (jika ada) alamat tersebut.

Bug bertingkat di thread yang sama

Ini berarti ada bug saat membuat laporan error HWASan. Hal ini biasanya disebabkan oleh adanya {i>bug <i}di HWASan, harap laporkan bug dan memberikan petunjuk cara merekonstruksi masalah jika memungkinkan.