AddressSanitizer

Genel bakış

C & C++ dilleri güçlü olsa da, program doğruluğunu ve program güvenliğini etkileyen bir hata sınıfından etkilenebilir. Visual Studio 2019 sürüm 16.9'dan başlayarak, Microsoft C/C++ derleyicisi (MSVC) ve IDE AddressSanitizer dezenfektanını destekler. AddressSanitizer (ASan), sıfır hatalı pozitif sonuçla bulunması zor birçok hatayı kullanıma sunan bir derleyici ve çalışma zamanı teknolojisidir:

Harcanan zamanınızı azaltmak için AddressSanitizer'ı kullanın:

  • Temel doğruluk
  • Platformlar arası taşınabilirlik
  • Güvenlik
  • Stres testi
  • Yeni kodu tümleştirme

Başlangıçta Google tarafından sunulan AddressSanitizer, mevcut derleme sistemlerinizi ve mevcut test varlıklarınızı doğrudan kullanan çalışma zamanı hata bulma teknolojileri sağlar.

AddressSanitizer, Visual Studio proje sistemi, CMake derleme sistemi ve IDE ile tümleşiktir. Projeler, bir proje özelliği ayarlayarak veya fazladan bir derleyici seçeneği kullanarak AddressSanitizer'ı etkinleştirebilir: /fsanitize=address. Yeni seçenek, x86 ve x64'ün tüm iyileştirme düzeyleri ve yapılandırmalarıyla uyumludur. Ancak düzenleme ve devam etme, artımlı bağlama ve /RTCile uyumlu değildir.

Visual Studio 2019 sürüm 16.9'dan başlayarak, Microsoft'un AddressSanitizer teknolojisi Visual Studio IDE ile tümleştirmeyi etkinleştirir. İşlev, dezenfektan çalışma zamanında bir hata bulduğunda isteğe bağlı olarak bir kilitlenme dökümü dosyası oluşturabilir. Programınızı çalıştırmadan önce ortam değişkenini ASAN_SAVE_DUMPS=MyFileName.dmp ayarlarsanız, kesin olarak tanılanmış hataların etkili bir son hata ayıklaması için ek meta veriler içeren bir kilitlenme dökümü dosyası oluşturulur. Bu döküm dosyaları, AddressSanitizer'ın genişletilmiş kullanımını aşağıdakiler için kolaylaştırır:

  • Yerel makine testi
  • Şirket içi dağıtılmış test
  • Test için bulut tabanlı iş akışları

AddressSanitizer'ı yükleme

Visual Studio Yükleyicisi C++ iş yükleri, AddressSanitizer kitaplıklarını ve IDE tümleştirmesini varsayılan olarak yükler. Ancak, Visual Studio 2019'un eski bir sürümünden yükseltme yapıyorsanız, yükseltmeden sonra ASan desteğini etkinleştirmek için Yükleyici'yi kullanın. Yükleyiciyi Visual Studio ana menüsünden Araçlar>Araçları ve Özellikleri Al... aracılığıyla açabilirsiniz. Aşağıdaki ekrana ulaşmak için Visual Studio Yükleyicisi mevcut Visual Studio yüklemenizde Değiştir'i seçin.

Visual Studio Yükleyicisi ekran görüntüsü. İsteğe bağlı bölümünün altındaki C++ AddressSanitizer bileşeni vurgulanır.

Not

Visual Studio'yu yeni güncelleştirmede çalıştırıyorsanız ancak ASan'ı yüklemediyseniz, kodunuzu çalıştırdığınızda bir hata alırsınız:

LNK1356: 'clang_rt.asan_dynamic-i386.lib' kitaplığı bulunamıyor

AddressSanitizer kullanma

Şu yaygın geliştirme yöntemlerinden herhangi birini kullanarak derleyici seçeneğiyle /fsanitize=address yürütülebilir dosyalarınızı oluşturmaya başlayın:

  • Komut satırı derlemeleri
  • Visual Studio proje sistemi
  • Visual Studio CMake tümleştirmesi

Yeniden derleyin, ardından programınızı normal şekilde çalıştırın. Bu kod oluşturma işlemi, çok sayıda hassas tanılanmış hata türünü kullanıma sunar. Bu hatalar üç yolla bildirilir: hata ayıklayıcı IDE'de, komut satırında veya hassas satır dışı işleme için yeni bir döküm dosyasında depolanır.

Microsoft, şu üç standart iş akışında AddressSanitizer kullanmanızı önerir:

Bu makalede, daha önce listelenen üç iş akışını etkinleştirmek için ihtiyacınız olan bilgiler yer alır. Bilgiler, AddressSanitizer'ın platforma bağımlı Windows 10 (ve üzeri) uygulamasına özgüdür. Bu belge, Google, Apple ve GCC tarafından yayımlanan mükemmel belgeleri tamamlar.

Not

Destek, Windows 10 ve sonraki sürümlerde x86 ve x64 ile sınırlıdır. Gelecek sürümlerde görmek istediğiniz şeyler hakkında bize geri bildirim gönderin. Geri bildiriminiz, gelecekte , , /fsanitize=leak, /fsanitize=memory/fsanitize=undefinedveya /fsanitize=hwaddressgibi /fsanitize=threaddiğer dezenfektanlara öncelik vermemize yardımcı olur. Sorunlarla karşılaşırsanız burada hata bildirebilirsiniz.

Geliştirici komut isteminden AddressSanitizer kullanma

/fsanitize=address AddressSanitizer çalışma zamanı için derlemeyi etkinleştirmek için geliştirici komut isteminde derleyici seçeneğini kullanın. Seçeneği /fsanitize=address , mevcut tüm C++ veya C iyileştirme düzeyleriyle (örneğin, /Od, /O1, /O2, /O2 /GLve PGO) uyumludur. seçeneği statik ve dinamik CRT'lerle (örneğin, /MD, /MDd, /MTve /MTd) çalışır. İSTER EXE ister DLL oluşturun, çalışır. Çağrı yığınlarının en iyi biçimlendirmesi için hata ayıklama bilgileri gereklidir. Aşağıdaki örnekte, cl /fsanitize=address /Zi komut satırına geçirilir.

AddressSanitizer kitaplıkları (.lib dosyaları) sizin için otomatik olarak bağlanır. Daha fazla bilgi için bkz . AddressSanitizer dili, derleme ve hata ayıklama başvurusu.

Örnek - temel genel arabellek taşması

// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
    printf("Hello!\n");
    x[100] = 5; // Boom!
    return 0;
}

Visual Studio 2019 için geliştirici komut istemi kullanma, kullanarak derleme main.cpp/fsanitize=address /Zi

AddressSanitizer seçenekleriyle derlenecek komutu gösteren komut isteminin ekran görüntüsü. Komut: 'cl main.cpp -faanitize-address /Zi'.

Sonucu main.exe komut satırında çalıştırdığınızda, aşağıdaki biçimlendirilmiş hata raporunu oluşturur.

Yedi önemli bilgiyi vurgulayan yer paylaşımlı kırmızı kutuları göz önünde bulundurun:

Temel genel taşma hatasını gösteren hata ayıklayıcının ekran görüntüsü.

Hata raporunda önemli bilgi parçalarını tanımlayan yedi kırmızı vurgu vardır. Bu ekran görüntüsünden sonra gelen numaralandırılmış listeye eşlenir. Numaralandırılmış kutular şu metni vurgular: 1) genel arabellek taşması 2) Boyut 4 3) basic-global-overflow.cpp 7 4) 'basic-global-overflow.cpp:3:8' 5) boyut 400 6) 00 00[f9]f9 f9 7) Kutusunda gölge bayt gösterge alanı var ve Genel kırmızı bölge var: f9

Yukarıdan aşağıya kırmızı vurgular

  1. Bellek güvenliği hatası genel arabellek taşmasıdır.
  2. Kullanıcı tanımlı herhangi bir değişkenin dışında 4 bayt (32 bit) depolandı .
  3. Depo, 7. satırdaki dosyada basic-global-overflow.cpp tanımlanan işlevde main() gerçekleşti.
  4. adlı x değişken, 8. sütundan başlayarak 3. satırdaki basic-global-overflow.cpp tanımlanır
  5. Bu genel değişken x 400 bayt boyutunda
  6. Mağaza tarafından hedeflenen adresi açıklayan tam gölge bayt değeri 0xf9
  7. Gölge bayt göstergesi 0xf9 , int x[100]

Not

Çağrı yığınındaki işlev adları, hata oluştuğunda çalışma zamanı tarafından çağrılan LLVM simgeleştiricisi aracılığıyla oluşturulur.

Visual Studio'da AddressSanitizer kullanma

AddressSanitizer, Visual Studio IDE ile tümleşiktir. MSBuild projesi için AddressSanitizer'ı açmak için Çözüm Gezgini'da projeye sağ tıklayın ve Özellikler'i seçin. Özellik Sayfaları iletişim kutusunda Yapılandırma Özellikleri>C/C++>Genel'i seçin, ardından AddressSanitizer'ı Etkinleştir özelliğini değiştirin. Değişikliklerinizi kaydetmek için Tamam'ı seçin.

AddressSanitizer'ı Etkinleştir özelliğini gösteren Özellik Sayfaları iletişim kutusunun ekran görüntüsü.

IDE'den derleme yapmak için uyumsuz seçeneklerden vazgeçin. (veya Hata Ayıklama modu) kullanılarak /Od derlenen mevcut bir proje için şu seçenekleri kapatmanız gerekebilir:

Hata ayıklayıcıyı derlemek ve çalıştırmak için F5 tuşuna basın. Visual Studio'da Özel Durum Oluşturuldu penceresi görüntülenir:

Genel arabellek taşması hatasını gösteren hata ayıklayıcının ekran görüntüsü.

Visual Studio'dan AddressSanitizer kullanma: CMake

Windows'u hedeflemek üzere oluşturulan bir CMake projesinde AddressSanitizer'ı etkinleştirmek için şu adımları izleyin:

  1. IDE'nin üst kısmındaki araç çubuğunda Yapılandırmalar açılan listesini açın ve Yapılandırmaları Yönet'i seçin.

    CMake yapılandırması açılan listesinin ekran görüntüsü. x64 Hata Ayıklama, x64 Sürümü vb. gibi seçenekleri görüntüler. Listenin en altında Yapılandırmaları Yönet... vurgulanır.

    Bu, projenizin dosyasının içeriğini yansıtan CMake Proje CMakeSettings.json Ayarları düzenleyicisini açar.

  2. Düzenleyicide JSON Düzenle bağlantısını seçin. Bu seçim görünümü ham JSON'a değiştirir.

  3. Adres Dezenfektanı'nı "windows-base" açmak için ön ayara "configurePresets": aşağıdaki kod parçacığını ekleyin:

    "environment": {
      "CFLAGS": "/fsanitize=address",
      "CXXFLAGS": "/fsanitize=address"
    }
    

    "configurePresets" daha sonra şuna benzer:

        "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. Yeni CMake projeleri için varsayılan olarak etkinleştirilen düzenle ve devam et (/ZI belirtilirse adres dezenfektanı çalışmaz. içindeCMakeLists.txt, ile set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"başlayan satırı açıklama satırına (ön ek) #ekleyin. Bu satır daha sonra şuna benzer:

    # 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. Bu JSON dosyasını kaydetmek için Ctrl+S tuşlarına basın

  6. CMake önbellek dizininizi temizleyin ve Visual Studio menüsünden seçim yaparak yeniden yapılandırın: Project>Delete cache ve Reconfigure. Önbellek dizininizi temizlemek ve yeniden yapılandırmak için istem görüntülendiğinde Evet'i seçin.

  7. Kaynak dosyanın içeriğini (örneğin, CMakeProject1.cpp) aşağıdakilerle değiştirin:

    // 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. Yeniden derlemek ve hata ayıklayıcı altında çalıştırmak için F5'i seçin.

    Bu ekran görüntüsü CMake derlemesinden gelen hatayı yakalar.

    Şu özel durumun ekran görüntüsü: Adres Temizleme Hatası: Genel arabellek taşması. Arka planda, adres dezenfektanı çıkışı komut penceresinde görünür.

AddressSanitizer kilitlenme bilgi dökümleri

AddressSanitizer'da bulut ve dağıtılmış iş akışlarıyla kullanılmak üzere yeni işlevler kullanıma sunulmuştur. Bu işlev, IDE'de bir AddressSanitizer hatasının çevrimdışı görüntülenmesine olanak tanır. Hata, canlı hata ayıklama oturumunda karşılaşacağınız gibi kaynağınızın üzerine geçer.

Bu yeni döküm dosyaları, bir hatayı analiz ederken verimliliklere yol açabilir. Yeniden çalıştırmanız, uzak verileri bulmanız veya devre dışı olan bir makineyi aramanız gerekmez.

Daha sonraki bir tarihte başka bir makinede Visual Studio'da görüntülenebilen yeni bir döküm dosyası türü oluşturmak için:

set ASAN_SAVE_DUMPS=MyFileName.dmp

Visual Studio 16.9'dan başlayarak, kaynak kodunuzun üzerinde dosyanızda *.dmp depolanan kesin olarak tanılanmış bir hata görüntüleyebilirsiniz.

Bu yeni kilitlenme dökümü işlevi bulut tabanlı iş akışlarına veya dağıtılmış testlere olanak tanır. Ayrıca herhangi bir senaryoda ayrıntılı, eyleme dönüştürülebilir bir hata oluşturmak için de kullanılabilir.

Örnek hatalar

AddressSanitizer çeşitli türlerde bellek kötüye kullanımı hatalarını algılayabilir. AddressSanitizer (/fsanitize=address) derleyici seçeneği kullanılarak derlenen ikili dosyaları çalıştırdığınızda bildirilen çalışma zamanı hatalarının birçoğu aşağıda belirtilmiştir:

Örnekler hakkında daha fazla bilgi için bkz . AddressSanitizer hata örnekleri.

Clang 12.0 ile farklılıklar

MSVC şu anda iki işlevsel alanda Clang 12.0'dan farklıdır:

  • stack-use-after-scope - Bu ayar varsayılan olarak açıktır ve kapatılamaz.
  • stack-use-after-return - Bu işlevsellik fazladan bir derleyici seçeneği gerektirir ve yalnızca ayarıyla ASAN_OPTIONSkullanılamaz.

Bu kararlar, bu ilk sürümü sunmak için gereken test matrisini azaltmak için alınmıştı.

Visual Studio 2019 16.9'da hatalı pozitiflere yol açabilecek özellikler dahil edilmedi. Bu disiplin, on yıllardır var olan kodlarla birlikte çalışmayı düşünürken gerekli olan etkili test bütünlüğünü zorunlu kıldı. Sonraki sürümlerde daha fazla özellik göz önünde bulundurulabilir:

Daha fazla bilgi için bkz . MSVC ile AddressSanitizer oluşturma.

Mevcut sektör belgeleri

AddressSanitizer teknolojisinin bu dil ve platforma bağımlı uygulamaları için kapsamlı belgeler zaten mevcuttur.

AddressSanitizer (dış) üzerindeki bu noktalı kağıt, uygulamayı açıklar.

Ayrıca bkz.

AddressSanitizer bilinen sorunları
AddressSanitizer derlemesi ve dil başvurusu
AddressSanitizer çalışma zamanı başvurusu
AddressSanitizer gölge baytları
AddressSanitizer bulut veya dağıtılmış test
AddressSanitizer hata ayıklayıcısı tümleştirmesi
AddressSanitizer hata örnekleri