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: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … 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
versusWRITE
) - 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):
- Daftar thread dalam proses
- Daftar thread dalam proses
- Nilai tag memori di dekat memori yang mengalami error
- 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.