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=addresskompatibel dengan semua tingkat pengoptimalan C++ atau C yang ada (misalnya, , , /Od/O1/O2, /O2 /GL, dan pengoptimalan terpandu profil). 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.

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:

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:

  1. Kompilasi /fsanitize-address-use-after-return menggunakan opsi .
  2. 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.

Baca 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