Bagikan melalui


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.

Cuplikan layar Alat Penginstal Visual Studio. Komponen C++ AddressSanitizer, di bawah bagian Opsional, disorot.

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 (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

Cuplikan layar perintah memperlihatkan perintah untuk dikompilasi dengan opsi AddressSanitizer. Perintahnya adalah: '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:

Cuplikan layar debugger memperlihatkan kesalahan luapan global dasar.

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

  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.

Cuplikan layar dialog Halaman Properti memperlihatkan properti Aktifkan AddressSanitizer.

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:

Cuplikan layar debugger memperlihatkan kesalahan luapan buffer global.

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.

    Cuplikan layar dropdown konfigurasi CMake. Ini menampilkan opsi seperti x64 Debug, x64 Release, dan sebagainya. Di bagian bawah daftar, Kelola Konfigurasi... disorot.

    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.

    Cuplikan layar pengecualian yang mengatakan: Kesalahan Pembersih Alamat: Luapan buffer global. Di latar belakang, output pembersih alamat terlihat di jendela perintah.

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 (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