Referensi bahasa, build, dan debugging AddressSanitizer
Bagian dalam artikel ini menjelaskan spesifikasi bahasa AddressSanitizer, opsi pengkompilasi, dan opsi linker. Mereka juga menjelaskan opsi yang mengontrol integrasi debugger Visual Studio khusus untuk AddressSanitizer.
Untuk informasi selengkapnya tentang runtime AddressSanitizer, lihat referensi runtime. Ini termasuk informasi tentang fungsi yang disadap dan cara mengaitkan alokator kustom. Untuk informasi selengkapnya tentang menyimpan crash dump dari kegagalan AddressSanitizer, lihat referensi crash dump.
Spesifikasi bahasa
__SANITIZE_ADDRESS__
Makro __SANITIZE_ADDRESS__
praprosesor didefinisikan sebagai 1
kapan /fsanitize=address
diatur. Makro ini berguna bagi pengguna tingkat lanjut untuk menentukan kode sumber secara kondisional untuk keberadaan runtime AddressSanitizer.
#include <cstdio>
int main() {
#ifdef __SANITIZE_ADDRESS__
printf("Address sanitizer enabled");
#else
printf("Address sanitizer not enabled");
#endif
return 1;
}
__declspec(no_sanitize_address)
Penentu __declspec(no_sanitize_address)
dapat digunakan untuk menonaktifkan sanitizer secara selektif pada fungsi, variabel lokal, atau variabel global. Ini __declspec
mempengaruhi perilaku pengkompilasi , bukan perilaku runtime .
__declspec(no_sanitize_address)
void test1() {
int x[100];
x[100] = 5; // ASan exception not caught
}
void test2() {
__declspec(no_sanitize_address) int x[100];
x[100] = 5; // ASan exception not caught
}
__declspec(no_sanitize_address) int g[100];
void test3() {
g[100] = 5; // ASan exception not caught
}
Kompilator
/fsanitize=address
opsi pengkompilasi
Opsi /fsanitize=address
kompilator melengkapi referensi memori dalam kode Anda untuk menangkap kesalahan keamanan memori saat runtime. Instrumentasi menghubungkan beban, penyimpanan, cakupan, alloca
, dan fungsi CRT. Ini dapat mendeteksi bug tersembunyi seperti out-of-bounds, use-after-free, use-after-scope, dan sebagainya. Untuk daftar kesalahan yang tidak ada yang terdeteksi saat runtime, lihat Contoh kesalahan AddressSanitizer.
/fsanitize=address
kompatibel dengan semua tingkat pengoptimalan C++ atau C yang ada (misalnya, /Od
, , /O1
/O2
, dan /O2 /GL
). Kode yang dihasilkan dengan opsi ini berfungsi dengan CRTs statis dan dinamis (misalnya, , /MD
, /MDd
/MT
, dan /MTd
). Opsi pengkompilasi ini dapat digunakan untuk membuat .EXE atau .DLL yang menargetkan x86 atau x64. Informasi debug diperlukan untuk pemformatan tumpukan panggilan yang optimal. Opsi pengompilasi ini tidak didukung dengan pengoptimalan yang dipandu profil.
Untuk contoh kode yang menunjukkan beberapa jenis deteksi kesalahan, lihat Contoh kesalahan AddressSanitizer.
/fsanitize=fuzzer
opsi pengkompilasi (eksperimental)
Opsi /fsanitize=fuzzer
pengkompilasi menambahkan LibFuzzer ke daftar pustaka default. Ini juga menetapkan opsi cakupan sanitizer berikut:
- Titik instrumentasi tepi (
/fsanitize-coverage=edge
), - penghitung 8-bit sebaris (
/fsanitize-coverage=inline-8bit-counters
), - perbandingan (
/fsanitize-coverage=trace-cmp
), dan - pembagian bilangan bulat (
/fsanitize-coverage=trace-div
).
Kami sarankan Anda menggunakan /fsanitize=address
dengan /fsanitize=fuzzer
.
Pustaka ini ditambahkan ke daftar pustaka default saat Anda menentukan /fsanitize=fuzzer
:
Opsi runtime | Pustaka LibFuzzer |
---|---|
/MT |
clang_rt.fuzzer_MT-{arch} |
/MD |
clang_rt.fuzzer_MD-{arch} |
/MTd |
clang_rt.fuzzer_MTd-{arch} |
/MDd |
clang_rt.fuzzer_MDd-{arch} |
Pustaka LibFuzzer yang menghilangkan main
fungsi juga tersedia. Anda bertanggung jawab untuk menentukan main
dan memanggil LLVMFuzzerInitialize
dan LLVMFuzzerTestOneInput
kapan Anda menggunakan pustaka ini. Untuk menggunakan salah satu pustaka ini, tentukan /NODEFAULTLIB
dan tautkan secara eksplisit dengan pustaka berikut yang sesuai dengan runtime dan arsitektur Anda:
Opsi runtime | Pustaka no_main LibFuzzer |
---|---|
/MT |
clang_rt.fuzzer_no_main_MT-{arch} |
/MD |
clang_rt.fuzzer_no_main_MD-{arch} |
/MTd |
clang_rt.fuzzer_no_main_MTd-{arch} |
/MDd |
clang_rt.fuzzer_no_main_MDd-{arch} |
Jika Anda menentukan /NODEFAULTLIB
dan tidak menentukan salah satu pustaka ini, Anda akan mendapatkan kesalahan tautan simbol eksternal yang belum terselesaikan.
/fsanitize-address-use-after-return
opsi pengkompilasi (eksperimental)
Secara default, pengkompilasi MSVC (tidak seperti Clang) tidak menghasilkan kode untuk mengalokasikan bingkai dalam tumpukan untuk menangkap kesalahan use-after-return. Untuk menangkap kesalahan ini menggunakan AddressSanitizer, Anda harus:
- Kompilasi
/fsanitize-address-use-after-return
menggunakan opsi . - Sebelum menjalankan program Anda, jalankan
set ASAN_OPTIONS=detect_stack_use_after_return=1
untuk mengatur opsi centang runtime.
Opsi ini /fsanitize-address-use-after-return
menyebabkan pengkompilasi menghasilkan kode untuk menggunakan bingkai tumpukan ganda dalam tumpukan ketika lokal dianggap "alamat diambil." Kode ini jauh lebih lambat daripada hanya menggunakan /fsanitize=address
sendirian. Untuk informasi selengkapnya dan contohnya, lihat Kesalahan: stack-use-after-return
.
Bingkai tumpukan ganda dalam tumpukan tetap ada setelah pengembalian dari fungsi yang membuatnya. Pertimbangkan contoh di mana alamat lokal, dialokasikan ke slot dalam timbunan, digunakan setelah pengembalian. Byte bayangan yang terkait dengan bingkai tumpukan palsu berisi nilai 0xF9. Itu 0xF9 berarti kesalahan stack-use-after-return saat runtime melaporkan kesalahan.
Bingkai tumpukan dialokasikan dalam tumpukan dan tetap setelah fungsi kembali. Runtime menggunakan pengumpulan sampah untuk membebaskan objek bingkai panggilan palsu ini secara asinkron, setelah interval waktu tertentu. Alamat penduduk lokal ditransfer ke bingkai persisten dalam timbunan. Ini adalah bagaimana sistem dapat mendeteksi kapan ada lokal yang digunakan setelah fungsi yang menentukan kembali. Untuk informasi selengkapnya, lihat algoritma untuk penggunaan tumpukan setelah pengembalian seperti yang didokumenkan oleh Google.
Linker
/INFERASANLIBS[:NO]
opsi linker
Opsi /fsanitize=address
pengkompilasi menandai objek untuk menentukan pustaka AddressSanitizer mana yang akan ditautkan ke dalam executable Anda. Pustaka memiliki nama yang dimulai dengan clang_rt.asan*
. Opsi /INFERASANLIBS
linker (aktif secara default) menautkan pustaka ini dari lokasi defaultnya secara otomatis. Berikut adalah pustaka yang dipilih dan ditautkan secara otomatis.
Catatan
Dalam tabel berikut, {arch}
adalah i386
atau x86_64
.
Pustaka ini menggunakan konvensi Clang untuk nama arsitektur. Konvensi MSVC biasanya x86
dan x64
bukan i386
dan x86_64
. Mereka merujuk ke arsitektur yang sama.
Opsi CRT | Pustaka runtime AddressSanitizer (.lib) | Biner runtime alamat (.dll) |
---|---|---|
/MT atau /MTd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD atau /MDd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
Opsi /INFERASANLIBS:NO
linker mencegah linker menautkan clang_rt.asan*
file pustaka dari lokasi default. Tambahkan jalur pustaka di skrip build Jika Anda menggunakan opsi ini. Jika tidak, linker melaporkan kesalahan simbol eksternal yang belum terselesaikan.
Versi Sebelumnya
Sebelum Visual Studio 17.7 Pratinjau 3, build yang ditautkan secara statis (/MT
atau /MTd
) tidak menggunakan dependensi DLL. Sebagai gantinya, runtime AddressSanitizer secara statis ditautkan ke EXE pengguna. Proyek DLL kemudian akan memuat ekspor dari EXE pengguna untuk mengakses fungsionalitas ASan. Selain itu, proyek yang ditautkan secara dinamis (/MD
atau /MTd
) menggunakan pustaka dan DLL yang berbeda tergantung pada apakah proyek dikonfigurasi untuk debug atau rilis. Untuk informasi selengkapnya tentang perubahan ini dan motivasinya, lihat MSVC Address Sanitizer – One DLL untuk semua Konfigurasi Runtime.
Opsi runtime CRT | DLL atau EXE | Pustaka runtime AddressSanitizer |
---|---|---|
/MT |
EXE | clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
/MT |
DLL | clang_rt.asan_dll_thunk-{arch} |
/MD |
Baik | clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
/MTd |
EXE | clang_rt.asan_dbg-{arch} , clang_rt.asan_dbg_cxx-{arch} |
/MTd |
DLL | clang_rt.asan_dbg_dll_thunk-{arch} |
/MDd |
Baik | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
Integrasi Visual Studio
/fno-sanitize-address-vcasan-lib
opsi pengkompilasi
Opsi /fsanitize=address
menautkan di pustaka tambahan untuk pengalaman penelusuran kesalahan Visual Studio yang ditingkatkan saat pengecualian AddressSanitizer dilemparkan. Pustaka ini disebut VCAsan. Pustaka memungkinkan Visual Studio menampilkan kesalahan AddressSanitizer pada kode sumber Anda. Mereka juga memungkinkan executable untuk menghasilkan crash dump saat laporan kesalahan AddressSanitizer dibuat. Untuk informasi selengkapnya, lihat Pustaka fungsionalitas yang diperluas Visual Studio AddressSanitizer.
Pustaka yang dipilih bergantung pada opsi pengkompilasi, dan secara otomatis ditautkan.
Opsi runtime | Versi VCAsan |
---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
Namun, jika Anda mengkompilasi menggunakan /Zl
(Hilangkan nama pustaka default), Anda harus menentukan pustaka secara manual. Jika tidak, Anda akan mendapatkan kesalahan tautan simbol eksternal yang belum terselesaikan. Berikut adalah beberapa contoh umum:
error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib
Penelusuran kesalahan yang ditingkatkan dapat dinonaktifkan pada waktu kompilasi dengan menggunakan /fno-sanitize-address-vcasan-lib
opsi .
ASAN_VCASAN_DEBUGGING
Variabel lingkungan
Opsi /fsanitize=address
kompilator menghasilkan biner yang mengekspos bug keamanan memori saat runtime. Ketika biner dimulai dari baris perintah, dan runtime melaporkan kesalahan, biner mencetak detail kesalahan. Kemudian keluar dari proses. Variabel ASAN_VCASAN_DEBUGGING
lingkungan dapat diatur untuk segera meluncurkan Visual Studio IDE saat runtime melaporkan kesalahan. Opsi pengkompilasi ini memungkinkan Anda melihat kesalahan, ditumbukkan melalui kode sumber Anda, pada baris dan kolom yang tepat yang menyebabkan kesalahan.
Untuk mengaktifkan perilaku ini, jalankan perintah set ASAN_VCASAN_DEBUGGING=1
sebelum Anda menjalankan aplikasi Anda. Anda dapat menonaktifkan pengalaman penelusuran kesalahan yang ditingkatkan dengan menjalankan set ASAN_VCASAN_DEBUGGING=0
.
Lihat juga
Gambaran umum AddressSanitizer
Masalah yang diketahui AddressSanitizer
Referensi runtime AddressSanitizer
Byte bayangan AddressSanitizer
AddressSanitizer cloud atau pengujian terdistribusi
Integrasi debugger AddressSanitizer
Contoh kesalahan AddressSanitizer