AddressSanitizer
Gambaran Umum
Bahasa C & C++ sangat kuat, tetapi dapat menderita kelas bug yang memengaruhi kebenaran program dan keamanan program. Mulai Visual Studio 2019 versi 16.9, pengkompilasi Microsoft C/C++ (MSVC) dan IDE mendukung sanitizer AddressSanitizer . AddressSanitizer (ASan) adalah teknologi kompilator dan runtime yang mengekspos banyak bug yang sulit ditemukan dengan nol positif palsu:
- Ketidakcocokan alokasi/dealloc dan/
new
delete
ketidakcocokan jenis - Alokasi terlalu besar untuk timbunan
calloc
luapan danalloca
luapan- Gratis ganda dan gunakan setelah gratis
- Luapan variabel global
- Luapan buffer timbunan
- Perataan nilai yang diratakan tidak valid
memcpy
danstrncat
parameter tumpang tindih- Stack buffer overflow dan underflow
- Stack gunakan setelah
return
dan gunakan setelah cakupan - Penggunaan memori setelah diracuni
Gunakan AddressSanitizer untuk mengurangi waktu yang Anda habiskan:
- Kebenaran dasar
- Portabilitas lintas platform
- Keamanan
- Tes tekanan
- Mengintegrasikan kode baru
AddressSanitizer, yang awalnya diperkenalkan oleh Google, menyediakan teknologi temuan bug runtime yang menggunakan sistem build yang ada dan aset pengujian yang ada secara langsung.
AddressSanitizer terintegrasi dengan sistem proyek Visual Studio, sistem build CMake, dan IDE. Proyek dapat mengaktifkan AddressSanitizer dengan mengatur properti proyek, atau dengan menggunakan satu opsi kompilator tambahan: /fsanitize=address
. Opsi baru kompatibel dengan semua tingkat pengoptimalan dan konfigurasi x86 dan x64. Namun, ini tidak kompatibel dengan edit-and-continue, penautan inkremental, dan /RTC
.
Mulai Visual Studio 2019 versi 16.9, teknologi AddressSanitizer Microsoft memungkinkan integrasi dengan Ide Visual Studio. Fungsionalitas dapat secara opsional membuat file crash dump ketika sanitizer menemukan bug saat runtime. Jika Anda mengatur ASAN_SAVE_DUMPS=MyFileName.dmp
variabel lingkungan sebelum menjalankan program, file crash dump dibuat dengan metadata tambahan untuk debugging pasca-mortem yang efisien dari bug yang didiagnosis dengan tepat. File cadangan ini mempermudah penggunaan AddressSanitizer yang diperluas untuk:
- Pengujian komputer lokal
- Pengujian terdistribusi lokal
- Alur kerja berbasis cloud untuk pengujian
Menginstal AddressSanitizer
Beban kerja C++ di Alat Penginstal Visual Studio menginstal pustaka AddressSanitizer dan integrasi IDE secara default. Namun, jika Anda memutakhirkan dari versi Visual Studio 2019 yang lebih lama, gunakan Penginstal untuk mengaktifkan dukungan ASan setelah peningkatan. Anda dapat membuka alat penginstal dari menu utama Visual Studio melalui Alat>Dapatkan Alat dan Fitur... Pilih Ubah pada penginstalan Visual Studio yang sudah ada dari Penginstal Visual Studio untuk masuk ke layar berikut.
Catatan
Jika Anda menjalankan Visual Studio pada pembaruan baru tetapi belum menginstal ASan, Anda akan mendapatkan kesalahan saat menjalankan kode:
LNK1356: tidak dapat menemukan pustaka 'clang_rt.asan_dynamic-i386.lib'
Gunakan AddressSanitizer
Mulai bangun executable Anda dengan /fsanitize=address
opsi kompilator menggunakan salah satu metode pengembangan umum ini:
- Build baris perintah
- Sistem proyek Visual Studio
- Integrasi Visual Studio CMake
Kompilasi ulang, lalu jalankan program Anda secara normal. Pembuatan kode ini mengekspos banyak jenis bug yang didiagnosis dengan tepat. Kesalahan ini dilaporkan dalam tiga cara: di IDE debugger, pada baris perintah, atau disimpan dalam jenis file cadangan baru untuk pemrosesan off-line yang tepat.
Microsoft menyarankan Anda menggunakan AddressSanitizer dalam tiga alur kerja standar ini:
Perulangan dalam pengembang
- Visual Studio - Baris perintah
- Visual Studio - Sistem proyek
- Visual Studio - CMake
CI/CD - integrasi berkelanjutan/ pengembangan berkelanjutan
- Pelaporan kesalahan - File cadangan AddressSanitizer baru
Fuzzing - bangunan dengan pembungkus libFuzzer
- Azure OneFuzz
- Komputer Lokal
Artikel ini membahas informasi yang Anda butuhkan untuk mengaktifkan tiga alur kerja yang tercantum sebelumnya. Informasi ini khusus untuk implementasi AddressSanitizer yang bergantung pada platform Windows 10 (dan yang lebih baru). Dokumentasi ini melengkapi dokumentasi luar biasa dari Google, Apple, dan GCC yang sudah diterbitkan.
Catatan
Dukungan terbatas pada x86 dan x64 pada Windows 10 dan yang lebih baru. Kirimi kami umpan balik tentang apa yang ingin Anda lihat dalam rilis mendatang. Umpan balik Anda membantu kami memprioritaskan sanitizer lain untuk masa depan, seperti /fsanitize=thread
, , /fsanitize=leak
/fsanitize=memory
, /fsanitize=undefined
, atau /fsanitize=hwaddress
. Anda dapat melaporkan bug di sini jika Mengalami masalah.
Menggunakan AddressSanitizer dari prompt perintah pengembang
/fsanitize=address
Gunakan opsi compiler di prompt perintah pengembang untuk mengaktifkan kompilasi untuk runtime AddressSanitizer. Opsi /fsanitize=address
ini kompatibel dengan semua tingkat pengoptimalan C++ atau C yang ada (misalnya, /Od
, , /O1
/O2
, /O2 /GL
, dan PGO
). Opsi ini berfungsi dengan CRD statis dan dinamis (misalnya, , /MD
, /MDd
/MT
, dan /MTd
). Ini berfungsi apakah Anda membuat EXE atau DLL. Informasi debug diperlukan untuk pemformatan tumpukan panggilan yang optimal. Dalam contoh berikut, cl /fsanitize=address /Zi
diteruskan pada baris perintah.
Pustaka AddressSanitizer (file.lib) ditautkan untuk Anda secara otomatis. Untuk informasi selengkapnya, lihat Referensi bahasa, build, dan penelusuran kesalahan AddressSanitizer.
Contoh - luapan buffer global dasar
// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
printf("Hello!\n");
x[100] = 5; // Boom!
return 0;
}
Menggunakan perintah pengembang untuk Visual Studio 2019, kompilasi main.cpp
menggunakan /fsanitize=address /Zi
Saat Anda menjalankan hasil main.exe
di baris perintah, itu membuat laporan kesalahan yang diformat yang mengikuti.
Pertimbangkan kotak merah yang dilapisi yang menyoroti tujuh informasi utama:
Ada tujuh sorotan merah yang mengidentifikasi potongan-potongan informasi utama dalam laporan kesalahan. Mereka memetakan ke daftar bernomor yang mengikuti cuplikan layar ini. Kotak bernomor menyoroti teks berikut: 1) global-buffer-overflow 2) TULIS ukuran 4 3) basic-global-overflow.cpp 7 4) di sebelah kanan variabel global 'x' yang ditentukan dalam 'basic-global-overflow.cpp:3:8' 5) ukuran 400 6) 00 00[f9]f9 f9 7) Box berada di area legenda byte bayangan dan berisi redzone Global: f9
Sorotan merah, dari atas ke bawah
- Bug keamanan memori adalah global-buffer-overflow.
- Ada 4 byte (32 bit) yang disimpan di luar variabel yang ditentukan pengguna.
- Penyimpanan berlangsung dalam fungsi
main()
yang ditentukan dalam filebasic-global-overflow.cpp
pada baris 7. - Variabel bernama
x
didefinisikan dalam basic-global-overflow.cpp pada baris 3, mulai dari kolom 8 - Variabel
x
global ini berukuran 400 byte - Byte bayangan yang tepat yang menjelaskan alamat yang ditargetkan oleh penyimpanan memiliki nilai
0xf9
- Legenda byte bayangan mengatakan
0xf9
adalah area padding di sebelah kananint x[100]
Catatan
Nama fungsi dalam tumpukan panggilan diproduksi melalui simbolizer LLVM yang dipanggil oleh runtime saat terjadi kesalahan.
Menggunakan AddressSanitizer di Visual Studio
AddressSanitizer terintegrasi dengan Ide Visual Studio. Untuk mengaktifkan AddressSanitizer untuk proyek MSBuild, klik kanan proyek di Penjelajah Solusi dan pilih Properti. Dalam dialog Halaman Properti, pilih Properti>Konfigurasi C/C++>General, lalu ubah properti Aktifkan AddressSanitizer. Pilih OK untuk menyimpan perubahan.
Untuk membangun dari IDE, pilih keluar dari opsi yang tidak kompatibel. Untuk proyek yang sudah ada yang dikompilasi dengan menggunakan /Od
(atau mode Debug), Anda mungkin perlu menonaktifkan opsi ini:
- Nonaktifkan edit dan lanjutkan
- Nonaktifkan
/RTC1
(pemeriksaan runtime) - Nonaktifkan
/INCREMENTAL
(penautan bertahap)
Untuk membangun dan menjalankan debugger, tekan F5. Jendela Pengecualian Yang Dilemparkan muncul di Visual Studio:
Menggunakan AddressSanitizer dari Visual Studio: CMake
Untuk mengaktifkan AddressSanitizer untuk proyek CMake yang dibuat untuk menargetkan Windows, ikuti langkah-langkah berikut:
Buka menu dropdown Konfigurasi di toolbar di bagian atas IDE dan pilih Kelola Konfigurasi.
Yang membuka editor Pengaturan Proyek CMake, yang mencerminkan konten file proyek
CMakeSettings.json
Anda.Pilih tautan Edit JSON di editor. Pilihan ini mengalihkan tampilan ke JSON mentah.
Tambahkan cuplikan berikut ke
"windows-base"
preset, di dalam"configurePresets":
untuk mengaktifkan Address Sanitizer:"environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" }
"configurePresets"
terlihat seperti ini, setelah itu:"configurePresets": [ { "name": "windows-base", "hidden": true, "generator": "Ninja", "binaryDir": "${sourceDir}/out/build/${presetName}", "installDir": "${sourceDir}/out/install/${presetName}", "cacheVariables": { "CMAKE_C_COMPILER": "cl.exe", "CMAKE_CXX_COMPILER": "cl.exe" }, "condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Windows" }, "environment": { "CFLAGS": "/fsanitize=address", "CXXFLAGS": "/fsanitize=address" } },
Pembersih alamat tidak berfungsi jika edit dan lanjutkan ditentukan (
/ZI
), yang diaktifkan secara default untuk proyek CMake baru. DiCMakeLists.txt
, komentar keluar (awalan dengan#
) baris yang dimulai denganset(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"
. Garis itu terlihat seperti ini, setelah itu:# set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
Masukkan Ctrl+S untuk menyimpan file JSON ini
Hapus direktori cache CMake Anda dan konfigurasi ulang dengan memilih dari menu Visual Studio: Project>Delete cache and Reconfigure. Pilih Ya saat perintah muncul untuk menghapus direktori cache Anda dan mengonfigurasi ulang.
Ganti konten file sumber (misalnya,
CMakeProject1.cpp
) dengan yang berikut ini:// CMakeProject1.cpp : Defines the entry point for the application #include <stdio.h> int x[100]; int main() { printf("Hello!\n"); x[100] = 5; // Boom! return 0; }
Pilih F5 untuk mengkompilasi ulang dan berjalan di bawah debugger.
Cuplikan layar ini menangkap kesalahan dari build CMake.
AlamatSanitizer crash dumps
Kami memperkenalkan fungsionalitas baru di AddressSanitizer untuk digunakan dengan cloud dan alur kerja terdistribusi. Fungsionalitas ini memungkinkan tampilan offline kesalahan AddressSanitizer di IDE. Kesalahan akan dilapisi di atas sumber Anda, seperti yang akan Anda alami dalam sesi debug langsung.
File cadangan baru ini dapat menyebabkan efisiensi saat menganalisis bug. Anda tidak perlu menjalankan ulang, atau menemukan data jarak jauh atau mencari mesin yang off-line.
Untuk menghasilkan jenis file cadangan baru yang dapat dilihat di Visual Studio di komputer lain di kemudian hari:
set ASAN_SAVE_DUMPS=MyFileName.dmp
Dimulai dengan Visual Studio 16.9 Anda dapat menampilkan kesalahan yang didiagnosis dengan tepat, disimpan dalam file Anda *.dmp
, di atas kode sumber Anda.
Fungsionalitas crash dump baru ini memungkinkan alur kerja berbasis cloud, atau pengujian terdistribusi. Ini juga dapat digunakan untuk mengajukan bug yang terperinci dan dapat ditindaklanjuti dalam skenario apa pun.
Contoh kesalahan
AddressSanitizer dapat mendeteksi beberapa jenis kesalahan penyalahgunaan memori. Berikut adalah banyak kesalahan runtime yang dilaporkan saat Anda menjalankan biner yang dikompilasi dengan menggunakan opsi pengkompilasi AddressSanitizer (/fsanitize=address
):
alloc-dealloc-mismatch
allocation-size-too-big
calloc-overflow
double-free
dynamic-stack-buffer-overflow
global-buffer-overflow
heap-buffer-overflow
heap-use-after-free
invalid-allocation-alignment
memcpy-param-overlap
new-delete-type-mismatch
stack-buffer-overflow
stack-buffer-underflow
stack-use-after-return
stack-use-after-scope
strncat-param-overlap
use-after-poison
Untuk informasi selengkapnya tentang contoh, lihat Contoh kesalahan AddressSanitizer.
Perbedaan dengan Clang 12.0
MSVC saat ini berbeda dari Clang 12.0 di dua area fungsi:
- stack-use-after-scope - pengaturan ini aktif secara default dan tidak dapat dinonaktifkan.
- stack-use-after-return - fungsionalitas ini memerlukan opsi pengkompilasi tambahan, dan tidak tersedia hanya dengan mengatur
ASAN_OPTIONS
.
Keputusan ini dibuat untuk mengurangi matriks pengujian yang diperlukan untuk memberikan versi pertama ini.
Fitur yang dapat menyebabkan positif palsu di Visual Studio 2019 16.9 tidak disertakan. Disiplin itu memberlakukan integritas pengujian efektif yang diperlukan ketika mempertimbangkan interop dengan puluhan tahun kode yang ada. Kemampuan lainnya dapat dipertimbangkan dalam rilis selanjutnya:
- Fiasco Pesanan Inisialisasi
- Intra Object Overflow
- Luapan Kontainer
- Pengurangan/Perbandingan Penunjuk
Untuk informasi selengkapnya, lihat Membangun untuk AddressSanitizer dengan MSVC.
Dokumentasi industri yang ada
Dokumentasi ekstensif sudah ada untuk implementasi bahasa dan tergantung platform dari teknologi AddressSanitizer ini.
Makalah mani ini pada AddressSanitizer (eksternal) menjelaskan implementasinya.
Lihat juga
Masalah yang diketahui AddressSanitizer
Referensi bahasa dan build AddressSanitizer
Referensi runtime AddressSanitizer
Byte bayangan AddressSanitizer
AddressSanitizer cloud atau pengujian terdistribusi
Integrasi debugger AddressSanitizer
Contoh kesalahan AddressSanitizer