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:

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.

Screenshot of the Visual Studio Installer. The C++ AddressSanitizer component, under the Optional section, is highlighted.

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:

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. Dokumentasi ini melengkapi dokumentasi luar biasa dari Google, Apple, dan GCC yang sudah diterbitkan.

Catatan

Dukungan saat ini terbatas pada x86 dan x64 pada Windows 10. 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

Screenshot of a command prompt showing the command to compile with AddressSanitizer options. The command is: `cl main.cpp -faanitize-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:

Screenshot of the debugger showing a basic global overflow error.

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) WRITE ukuran 4 3) basic-global-overflow.cpp 7 4) di sebelah kanan variabel global 'x' yang ditentukan dalam 'basic-overflow.cpp 7 4) di sebelah kanan variabel global 'x' yang ditentukan dalam 'basic-overflow.cpp 7 4) di sebelah kanan variabel global 'x' yang ditentukan dalam 'basic-overflow.cpp 7 4) 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

  1. Bug keamanan memori adalah global-buffer-overflow.
  2. Ada 4 byte (32 bit) yang disimpan di luar variabel yang ditentukan pengguna.
  3. Penyimpanan berlangsung dalam fungsi main() yang ditentukan dalam file basic-global-overflow.cpp pada baris 7.
  4. Variabel bernama x didefinisikan dalam basic-global-overflow.cpp pada baris 3, mulai dari kolom 8
  5. Variabel x global ini berukuran 400 byte
  6. Byte bayangan yang tepat yang menjelaskan alamat yang ditargetkan oleh penyimpanan memiliki nilai0xf9
  7. Legenda byte bayangan mengatakan 0xf9 adalah area padding di sebelah kanan int 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.

Screenshot of the Property Pages dialog showing the Enable AddressSanitizer property.

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:

Untuk membangun dan menjalankan debugger, tekan F5. Jendela Pengecualian Yang Dilemparkan muncul di Visual Studio:

Screenshot of the debugger showing a global buffer overflow error.

Menggunakan AddressSanitizer dari Visual Studio: CMake

Untuk mengaktifkan AddressSanitizer untuk proyek CMake yang dibuat untuk menargetkan Windows, ikuti langkah-langkah berikut:

  1. Buka menu dropdown Konfigurasi di toolbar di bagian atas IDE dan pilih Kelola Konfigurasi.

    Screenshot of the CMake configuration dropdown. It displays options like x64 Debug, x64 Release, and so on. At the bottom of the list, Manage Configurations... is highlighted.

    Yang membuka editor Pengaturan Proyek CMake, yang mencerminkan konten file proyek CMakeSettings.json Anda.

  2. Pilih tautan Edit JSON di editor. Pilihan ini mengalihkan tampilan ke JSON mentah.

  3. 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"
            }
          },
    
  4. Pembersih alamat tidak berfungsi jika edit dan lanjutkan ditentukan (/ZI), yang diaktifkan secara default untuk proyek CMake baru. Di CMakeLists.txt, komentar keluar (awalan dengan #) baris yang dimulai dengan set(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>>")
    
  5. Masukkan Ctrl+S untuk menyimpan file JSON ini

  6. 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.

  7. 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;
    }
    
  8. Pilih F5 untuk mengkompilasi ulang dan berjalan di bawah debugger.

    Cuplikan layar ini menangkap kesalahan dari build CMake.

    Screenshot of an exception that says: Address Sanitizer Error: Global buffer overflow. In the background, address sanitizer output is visible in command window.

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):

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:

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 menjelaskan implementasinya.

Baca 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