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:
- Alloc/dealloc uyuşmazlıkları ve
new
/delete
tür uyuşmazlıkları - Ayırmalar yığın için çok büyük
calloc
taşma vealloca
taşma- Çift ücretsiz ve ücretsiz sonra kullanın
- Genel değişken taşması
- Yığın arabellek taşması
- Hizalanmış değerlerin geçersiz hizalaması
memcpy
vestrncat
parametre çakışması- Yığın arabellek taşması ve yetersizlik
- Kapsam sonrasında
return
yığın kullanımı ve sonra kullanma - Zehirlendikten sonra bellek kullanımı
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 /RTC
ile 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.
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:
Geliştirici iç döngüsü
- Visual Studio - Komut satırı
- Visual Studio - Proje sistemi
- Visual Studio - CMake
CI/CD - sürekli tümleştirme / sürekli geliştirme
- Hata raporlama - Yeni AddressSanitizer döküm dosyaları
Fuzzing - libFuzzer sarmalayıcı ile bina
- Azure OneFuzz
- Yerel Makine
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=undefined
veya /fsanitize=hwaddress
gibi /fsanitize=thread
diğ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 /GL
ve PGO
) uyumludur. seçeneği statik ve dinamik CRT'lerle (örneğin, /MD
, /MDd
, /MT
ve /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
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:
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
- Bellek güvenliği hatası genel arabellek taşmasıdır.
- Kullanıcı tanımlı herhangi bir değişkenin dışında 4 bayt (32 bit) depolandı .
- Depo, 7. satırdaki dosyada
basic-global-overflow.cpp
tanımlanan işlevdemain()
gerçekleşti. - adlı
x
değişken, 8. sütundan başlayarak 3. satırdaki basic-global-overflow.cpp tanımlanır - Bu genel değişken
x
400 bayt boyutunda - Mağaza tarafından hedeflenen adresi açıklayan tam gölge bayt değeri
0xf9
- 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.
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:
- Düzenlemeyi kapatın ve devam edin
/RTC1
Kapatma (çalışma zamanı denetimleri)/INCREMENTAL
Kapatma (artımlı bağlama)
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:
Visual Studio'dan AddressSanitizer kullanma: CMake
Windows'u hedeflemek üzere oluşturulan bir CMake projesinde AddressSanitizer'ı etkinleştirmek için şu adımları izleyin:
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.
Bu, projenizin dosyasının içeriğini yansıtan CMake Proje
CMakeSettings.json
Ayarları düzenleyicisini açar.Düzenleyicide JSON Düzenle bağlantısını seçin. Bu seçim görünümü ham JSON'a değiştirir.
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" } },
Yeni CMake projeleri için varsayılan olarak etkinleştirilen düzenle ve devam et (
/ZI
belirtilirse adres dezenfektanı çalışmaz. içindeCMakeLists.txt
, ileset(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>>")
Bu JSON dosyasını kaydetmek için Ctrl+S tuşlarına basın
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.
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; }
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.
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:
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
Ö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_OPTIONS
kullanı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