Dokumen ini menunjukkan cara mengaktifkan alat proses debug khusus saat menggunakan AGDE. Alat ini dapat membantu mengatasi kerusakan memori yang sulit didiagnosis dan menimpa error.
HWAddress Sanitizer dan Address Sanitizer
HWAddress Sanitizer (HWASan) dan Address Sanitizer (ASan) adalah alat proses debug kerusakan memori yang membantu proses debug kerusakan memori dan menimpa error, seperti berikut:
- Overflow dan underflow buffer stack
- Overflow dan underflow buffer heap
- Penggunaan stack di luar cakupannya
- Error double free dan wild free
- Penggunaan stack setelah ditampilkan (khusus HWASan)
Sebaiknya aktifkan HWASan atau ASan hanya saat Anda men-debug masalah atau sebagai bagian dari pengujian otomatis. Meskipun alat ini berperforma tinggi, penggunaannya menimbulkan penalti.
Perilaku runtime
Jika diaktifkan, HWASan dan ASan akan otomatis memeriksa kerusakan memori di aplikasi Anda.
Jika error memori terdeteksi, aplikasi akan mengalami error dengan error SIGBART
(pembatalan sinyal) dan mencetak pesan mendetail ke logcat. Salinan pesan ini
juga ditulis ke file di bagian /data/tombstones
.
Pesan error terlihat mirip dengan yang berikut ini:
ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
#0 0x7b24d90a08 (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
#1 0x7b8f1e4ccc (/apex/com.android.art/lib64/libart.so+0x198ccc)
#2 0x7b8f1db364 (/apex/com.android.art/lib64/libart.so+0x18f364)
#3 0x7b8f2ad8d4 (/apex/com.android.art/lib64/libart.so+0x2618d4)
0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
#0 0x7b92a322bc (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
#1 0x7b24d909e0 (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
#2 0x7b8f1e4ccc (/apex/com.android.art/lib64/libart.so+0x198ccc)
Prasyarat
Persyaratan HWASan
Untuk menggunakan HWASan:
- Anda harus menggunakan AGDE 24.1.99 atau yang lebih tinggi.
- Aplikasi harus di-build menggunakan NDK 26 atau yang lebih tinggi.
- Aplikasi harus di-build dengan target SDK 34 atau yang lebih tinggi.
- Target harus berupa perangkat
arm64-v8a
yang menjalankan Android 14 (API level 34) atau yang lebih tinggi.
Menggunakan Library Standar C++ bersama dalam project Anda
Karena masalah umum, ASan tidak kompatibel dengan penanganan pengecualian C++ saat menggunakan libc++_static
. Masalah ini tidak terlihat saat menggunakan libc++_shared
.
HWASan memiliki implementasi operator new
dan delete
sendiri, yang tidak dapat
digunakan jika library standar ditautkan secara statis ke project.
Untuk mengubah setelan ini, lihat bagian Menautkan Library Standar C++ dalam dokumen ini.
Mengaktifkan pembuatan Frame Pointer
HWASan dan ASan menggunakan unwinder berbasis frame pointer cepat dalam membuat informasi stack trace untuk peristiwa alokasi dan dealokasi memori. Ini berarti Anda harus mengaktifkan pembuatan pointer frame di setelan compiler C++ untuk menggunakan fitur ini. Artinya, Anda perlu menonaktifkan pengoptimalan penghilangan frame pointer.
Untuk mengubah setelan ini, lihat bagian Mengaktifkan pembuatan Frame Pointer dalam dokumen ini.
Mengonfigurasi project Visual Studio Anda untuk menggunakan HWASan atau ASan
Mengaktifkan HWASan atau ASan
Untuk mengaktifkan HWASan atau ASan, buka Configuration Properties > General di Property Pages untuk project Anda.
Gambar 1: Opsi Property project di jendela Visual Studio Solution Explorer.
Gambar 2: Setelan Address Sanitizer (ASan) di properti project umum.
Untuk mengaktifkan HWASan untuk project Anda, ubah setelan Address Sanitizer (ASan) menjadi Hardware ASan Enabled (fsanitize=hwaddress).
Untuk mengaktifkan ASan untuk project Anda, ubah setelan Address Sanitizer (ASan) menjadi ASan Enabled (fsanitize=address).
Mengaktifkan pembuatan Frame Pointer
Pembuatan Frame Pointer dikontrol oleh setelan compiler C/C++ Omit Frame Pointer dan dapat ditemukan di Property Pages project di bagian Configuration Properties > C/C++ > Optimization.
Gambar 3: Tempat untuk menemukan setelan Omit Frame Pointer.
Saat menggunakan HWASan atau ASan, tetapkan setelan Omit Frame Pointer ke No (-fno-omit-frame-pointer).
Menautkan Library Standar C++ dalam mode library bersama
Setelan mode penaut untuk Library Standar C++ dapat ditemukan di Property Pages project Anda di bagian Configuration Properties > General, di bagian Project Defaults.
Gambar 4: Tempat menemukan setelan mode penaut untuk Library Standar C++.
Saat menggunakan HWASan atau ASan, tetapkan Use of STL ke Use C++ Standard Libraries (.so). Nilai ini menautkan library standar C++ ke project Anda sebagai library bersama, yang diperlukan agar HWASan dan ASan dapat berfungsi dengan benar.
Membuat Konfigurasi Build untuk penggunaan Address Sanitizer
Jika Anda lebih suka menggunakan HWASan atau ASan untuk sementara, sebaiknya jangan membuat konfigurasi build baru hanya untuk penggunaannya. Hal ini mungkin terjadi jika project Anda kecil, Anda sedang menjelajahi fitur, atau sebagai respons atas masalah yang Anda temukan selama pengujian.
Namun, jika menurut Anda HWASan atau ASan berguna dan berencana menggunakannya secara rutin, sebaiknya buat konfigurasi build baru untuk HWASan atau ASan seperti yang ditunjukkan dalam contoh Teapot. Anda mungkin melakukannya jika, misalnya, secara rutin menjalankan Address Sanitizer sebagai bagian dari pengujian unit, atau selama pengujian asap dalam game semalam.
Membuat konfigurasi build terpisah mungkin sangat berguna jika Anda memiliki project besar yang menggunakan banyak library pihak ketiga yang berbeda tempat Anda biasanya menautkannya secara statis dengan library standar C++. Konfigurasi build khusus dapat membantu memastikan bahwa setelan project Anda selalu akurat setiap saat.
Untuk membuat konfigurasi build, dari Property Pages project Anda, klik
tombol
Configuration Manager…, lalu buka
menu drop-down Active solution configuration. Kemudian, pilih
Menggunakan HWASan dengan alokator memori kustom
HWASan secara otomatis mencegat memori yang dialokasikan melalui malloc
(atau new
)
sehingga dapat memasukkan tag ke dalam pointer dan memeriksa ketidakcocokan tag.
Namun, saat menggunakan alokator memori kustom, HWASan tidak dapat otomatis mencegat metode alokasi memori kustom Anda. Oleh karena itu, jika Anda ingin menggunakan HWASan dengan alokator memori kustom, instrumentasikan alokator memori untuk memanggil HWASan secara eksplisit. Hal ini dapat dilakukan hanya dengan beberapa baris kode.
Prasyarat
Metode HWASan yang perlu Anda panggil ditentukan di header ini:
#include "sanitizer/hwasan_interface.h"
Menginstrumentasikan metode alokasi memori
Alokasikan objek pada perincian dan perataan blok 16 byte. Misalnya, jika Anda memiliki alokator kumpulan yang menayangkan objek berukuran tetap berukuran 24 byte, bulatkan alokasi Anda hingga 32 byte, dan selaraskan ke 16 byte.
Buat tag 8-bit. Tag Anda tidak boleh menggunakan nilai 0-16, karena nilai tersebut disediakan untuk penggunaan internal.
Aktifkan HWASan untuk mulai melacak region memori dengan tag tersebut:
__hwasan_tag_memory((void*) address, tag, size);
Masukkan tag ke 8-bit atas pointer Anda:
address = __hwasan_tag_pointer((void*) address, tag);
Membuat instrumen metode dealokasi memori
Reset tag untuk region memori agar akses lebih lanjut melalui pointer bertag yang ada gagal:
__hwasan_tag_memory(__hwasan_tag_pointer(ptr, 0), 0, size);
Bekerja dengan kumpulan objek yang dialokasikan sebelumnya
Jika alokator memori Anda mengalokasikan objek di kumpulan dan mengembalikan objek kembali ke kumpulan, bukan benar-benar membebaskannya, metode pengalokasian ulang Anda dapat langsung menimpa tag untuk memori dan pointer dengan nilai baru:
```
__hwasan_tag_memory(__hwasan_tag_pointer(ptr, 0), tag, size);
ptr = __hwasan_tag_pointer((void*)ptr, tag);
```
Jika Anda menggunakan teknik ini, metode alokasi tidak perlu memberi tag pada pointer atau blok memori, tetapi memberi tag pada pointer dan blok memori saat Anda mengalokasikan objek di kumpulan. Lihat contoh PoolAllocator untuk contoh yang menggunakan gaya ini.