Aracılığıyla paylaş


AddressSanitizer çalışma zamanı

AddressSanitizer çalışma zamanı kitaplığı, bellek erişimlerinin denetlenebilmesi için ortak bellek ayırma işlevlerini ve işlemlerini durdurur. Derleyicinin oluşturabileceği çeşitli yürütülebilir dosya türlerini destekleyen birkaç farklı çalışma zamanı kitaplığı vardır. Derleme zamanında seçeneğini geçirdiğiniz /fsanitize=address sürece derleyici ve bağlayıcı uygun çalışma zamanı kitaplıklarını otomatik olarak bağlar. Bağlantı zamanında seçeneğini kullanarak /NODEFAULTLIB varsayılan davranışı geçersiz kılabilirsiniz. Daha fazla bilgi için AddressSanitizer dili, derleme ve hata ayıklama başvurusundaki bağlama bölümüne bakın.

ile cl /fsanitize=addressderlenirken, derleyici gölge baytları yönetmek ve denetlemek için yönergeler oluşturur. Programınız yığındaki, yığındaki veya genel kapsamdaki bellek erişimlerini denetlemek için bu izleme aracını kullanır. Derleyici ayrıca yığın ve genel değişkenleri açıklayan meta veriler de üretir. Bu meta veriler çalışma zamanının kaynak kodunuzda işlev adları, satırlar ve sütunlar gibi kesin hata tanılamaları oluşturmasını sağlar. Derleyici denetimleri ve çalışma zamanı kitaplıkları, çalışma zamanında karşılaşılırsa birçok türde bellek güvenliği hatasını tam olarak tanılayabilir.

Visual Studio 17.7 Preview 3 sürümünden itibaren AddressSanitizer çalışma zamanına bağlanmaya yönelik çalışma zamanı kitaplıklarının listesi aşağıda belirtilmiştir. (çalışma zamanını statik olarak bağlama) ve /MD (çalışma zamanında yeniden oluşturucuyu dinamik olarak bağlama) seçenekleri hakkında /MT daha fazla bilgi için bkz. /MD, /MT, /LD (Çalışma Zamanı Kitaplığını Kullanma).

Not

Aşağıdaki tabloda {arch} veya x86_64şeklindediri386. Bu kitaplıklar mimari adları için Clang kurallarını kullanır. MSVC kuralları normal olarak x86 ve yerine i386 ve x64 x86_64şeklindedir, ancak aynı mimarilere başvurur.

CRT seçeneği AddressSanitizer çalışma zamanı kitaplığı (.lib) Adres çalışma zamanı ikili (.dll)
/MT veya /MTd clang_rt.asan_dynamic-{arch}, clang_rt.asan_static_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}
/MD veya /MDd clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}

Aşağıdaki diyagramda, , , /MTd/MDve /MDd derleyici seçenekleri için /MTdil çalışma zamanı kitaplıklarının nasıl bağlanıyor olduğu gösterilmektedir:

Çeşitli derleyici seçenekleri için çalışma zamanı kitaplıklarının nasıl bağlanıyor diyagramı.

Görüntüde çalışma zamanı kitaplığını bağlamaya yönelik üç senaryo gösterilmektedir. İlki /MT veya /MTd'dir. My_exe.exe ve my_dll.dll statik olarak bağlı VCRuntime, Evrensel CRT ve C++ çalışma zamanlarının kendi kopyalarıyla gösterilir. Senaryolarda hem my_exe.exe hem de my_dll.dll vcruntime140.dll, ucrtbase.dll ve msvcp140.dll paylaştığı /MD gösterilir. Son senaryoda hem my_exe.exe hem de my_dll.dll çalışma zamanlarının hata ayıklama sürümlerini paylaştığı /MDd gösterilmektedir: vcruntime140d.dll, ucrtbased.dll ve msvcp140d.dll

Aşağıdaki diyagramda, çeşitli derleyici seçenekleri için ASan kitaplığının nasıl bağlı olduğu gösterilmektedir:

ASan çalışma zamanı dll'sinin nasıl bağlı olduğunu gösteren diyagram.

Resimde, ASan çalışma zamanı kitaplığını bağlamak için dört senaryo gösterilmektedir. Senaryolar /MT (çalışma zamanını statik olarak bağlama), /MTd (hata ayıklama çalışma zamanını statik olarak bağlama), /MD (çalışma zamanında yeniden oluşturucuyu dinamik olarak bağlama), /MDd (çalışma zamanında hata ayıklama yeniden oluşturucuyu dinamik olarak bağlama) içindir. Her durumda, my_exe.exe bağlantıları ve iş ortakları tek bir clang-rt.asan-dynamix-x86_64.dll örneğine my_dll.dll bağlantı sağlar.

Statik olarak bağlanırken bile, diğer C Runtime bileşenlerinden farklı olarak ASan çalışma zamanı DLL'si çalışma zamanında mevcut olmalıdır.

Önceki sürümler

Visual Studio 17.7 Preview 3'e geçmeden önce, statik olarak bağlı (/MT veya /MTd) derlemelerde DLL bağımlılığı kullanılmamıştı. Bunun yerine, AddressSanitizer çalışma zamanı statik olarak kullanıcının EXE'sine bağlandı. DLL projeleri daha sonra ASan işlevselliğine erişmek için kullanıcının EXE dosyasından dışarı aktarmaları yükler.

Dinamik olarak bağlı projeler (/MD veya ), projenin hata ayıklama veya /MDdsürüm için yapılandırılıp yapılandırılmadığına bağlı olarak farklı kitaplıklar ve DLL'ler kullandı. Bu değişiklikler ve bunların motivasyonları hakkında daha fazla bilgi için bkz . MSVC Adres Temizleme – Tüm Çalışma Zamanı Yapılandırmaları için Bir DLL.

Aşağıdaki tabloda, Visual Studio 17.7 Preview 3'e geçmeden önce AddressSanitizer çalışma zamanı kitaplığı bağlantısının önceki davranışı açıklanmaktadır:

CRT seçeneği DLL veya EXE HATA AYIKLAMA? ASan kitaplığı (.lib) ASan çalışma zamanı ikili dosyası (.dll)
/MT EXE Hayır clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch} Hiçbiri
/MT DLL Hayır clang_rt.asan_dll_thunk-{arch} None
/MD İkisinden biri Hayır clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} clang_rt.asan_dynamic-{arch}
/MT EXE Yes clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch} Hiçbiri
/MT DLL Yes clang_rt.asan_dbg_dll_thunk-{arch} Hiçbiri
/MD Herhangi biri Yes clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} clang_rt.asan_dbg_dynamic-{arch}

Aşağıdaki diyagramda, Visual Studio 2022 17.7 Preview 3'e geçmeden önce çeşitli derleyici seçenekleri için ASan kitaplığının nasıl bağlandığını gösterilmektedir:

Visual Studio 2022 Preview 3 öncesinde ASan çalışma zamanı dll'sinin nasıl bağlandığını gösteren diyagram.

Resimde, ASan çalışma zamanı kitaplığını bağlamak için dört senaryo gösterilmektedir. Senaryolar /MT (çalışma zamanını statik olarak bağlama), /MTd (hata ayıklama çalışma zamanını statik olarak bağlama), /MD (çalışma zamanında yeniden oluşturucuyu dinamik olarak bağlama), /MDd (çalışma zamanında hata ayıklama yeniden oluşturucuyu dinamik olarak bağlama) içindir. /MT için my_exe.exe, ASan çalışma zamanının statik olarak bağlı bir kopyasına sahiptir. my_exe.exe'da ASan çalışma zamanına bağlantılar my_dll.dll. /MTd için diyagram, statik olarak bağlı ASan çalışma zamanının hata ayıklamasını kullanması dışında aynıdır. /MD için hem my_exe.exe hem de my_dll.dll clang_rt.asan_dynamic-x86_64.dll adlı dinamik olarak bağlı ASan çalışma zamanına bağlantı sağlar. /MDd için diyagram, my_exe.exe ve clang_rt.asan_dbg_dynamic-x86_64.dll adlı hata ayıklama ASan çalışma zamanına my_dll.dll bağlantısı dışında aynıdır.

İşlev kesme

AddressSanitizer, birçok kısayol düzeltme eki oluşturma tekniğiyle işlev kesme işlemine ulaşır. Bu teknikler en iyi şekilde kaynak kodun içinde belgelenir.

Çalışma zamanı kitaplıkları birçok yaygın bellek yönetimi ve bellek işleme işlevini durdurur. Liste için bkz . Araya alınan işlevlerin AddressSanitizer listesi. Ayırma kesicileri, her ayırma çağrısıyla ilgili meta verileri ve gölge baytları yönetir. veya delete gibi malloc bir CRT işlevi her çağrıldığında, kesme noktaları AddressSanitizer gölge bellek bölgesinde belirli değerler ayarlayarak bu yığın konumlarının şu anda erişilebilir olup olmadığını ve ayırma sınırlarının ne olduğunu gösterir. Bu gölge baytlar, bir yükün veya deponun geçerli olup olmadığını belirlemek için derleyici tarafından oluşturulan gölge bayt denetimlerine olanak sağlar.

Kesme işleminin başarılı olması garanti edilmez. Bir işlev prologu yazılamayacak kadar kısaysa jmp , kesme başarısız olabilir. Bir kesme hatası oluşursa, program bir debugbreak oluşturur ve durur. Hata ayıklayıcı eklerseniz, kesme sorununun nedeni net olur. Bu sorun varsa bir hata bildirin.

Not

Kullanıcılar isteğe bağlı olarak ortam değişkenini ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE herhangi bir değere ayarlayarak başarısız bir kesme noktasını aşmaya devam edebilir. Kesme hatasının devam etmesi, bu işlev için hata raporlarının kaçırılmasıyla sonuçlanabilir.

Özel ayırıcılar ve AddressSanitizer çalışma zamanı

AddressSanitizer çalışma zamanı , malloc/free,deleteHeapFree/HeapAlloc/new (aracılığıylaRtlAllocateHeap/RtlFreeHeap) yaygın ayırıcı arabirimleri için kesme noktaları sağlar. Birçok program, özel ayırıcıları bir nedenle veya başka bir nedenle kullanır; arabirimini kullanan dlmalloc herhangi bir program veya ve VirtualAlloc()kullanan std::allocator bir çözüm örnek olabilir. Derleyici, özel ayırıcıya otomatik olarak gölge bellek yönetim çağrıları ekleyemiyor. Sağlanan el ile zehirlenme arabirimini kullanmak kullanıcının sorumluluğundadır. Bu API, bu ayırıcıların mevcut AddressSanitizer çalışma zamanı ve gölge bayt kurallarıyla düzgün çalışmasını sağlar.

El ile AdresSanitizer zehirlendiricisi arabirimi

Aydınlatma arabirimi basittir, ancak kullanıcıya hizalama kısıtlamaları uygular. Kullanıcılar bu prototipleri içeri aktararak içeri aktarabilir sanitizer/asan_interface.h. Arabirim işlevi prototipleri şunlardır:

void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);

Kolaylık sağlamak için, AddressSanitizer arabirimi üst bilgi dosyası sarmalayıcı makroları sağlar. Bu makrolar, derleme sırasında AddressSanitizer işlevinin etkinleştirilip etkinleştirilmediğini denetler. Kaynak kodunuzun gerekli olmadığında zehirlenme işlevi çağrılarını atmasına izin verir. Bu makrolar, yukarıdaki işlevleri doğrudan çağırmak yerine tercih edilmelidir:

#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)

AddressSanitizer zehirlenmesi için hizalama gereksinimleri

Gölge baytların el ile zehirlenmesi, hizalama gereksinimlerini dikkate almalıdır. Gölge baytların gölge bellekteki bayt sınırında bitmesi için kullanıcının gerekirse doldurma eklemesi gerekir. AddressSanitizer gölge belleğindeki her bit, uygulamanın belleğindeki tek bir bayt durumunu kodlar. Bu kodlama, doldurma dahil olmak üzere her ayırmanın toplam boyutunun 8 baytlık bir sınıra hizalanmış olması gerektiği anlamına gelir. Hizalama gereksinimi karşılanmadıysa yanlış hata raporlamaya yol açabilir. Yanlış raporlama, eksik raporlar (hatalı negatifler) veya hata olmayan raporlar (yanlış pozitifler) olarak bildirebilir.

Hizalama gereksinimini ve olası sorunları gösteren bir çizim için, sağlanan ASan hizalama örneklerine bakın. Bunlardan biri, el ile gölge bellek zehirlenmesinde neyin yanlış gidebileceğini gösteren küçük bir programdır. İkincisi, arabirimi kullanılarak el ile zehirlenmenin örnek bir uygulamasıdır std::allocator .

Çalışma zamanı seçenekleri

Microsoft C/C++ (MSVC), llvm-project deposundaki Clang AddressSanitizer çalışma zamanını temel alan bir çalışma zamanı kullanır. Bu nedenle, çalışma zamanı seçeneklerinin çoğu iki sürüm arasında paylaşılır. Genel Clang çalışma zamanı seçeneklerinin tam listesi burada bulunabilir. İzleyen bölümlerde bazı farkları belgeledik. Beklendiği gibi çalışmayan seçenekler bulursanız bir hata bildirin.

Desteklenmeyen AddressSanitizer seçenekleri

  • detect_container_overflow
  • unmap_shadow_on_exit

Not

AddressSanitizer çalışma zamanı seçeneği halt_on_error beklediğiniz gibi çalışmaz. Hem Clang hem de MSVC çalışma zamanı kitaplıklarında, bellek bozulması hatalarının çoğu dahil olmak üzere birçok hata türü devam edilemez olarak kabul edilir.

Daha fazla bilgi için Clang 12.0 ile Farklılıklar bölümüne bakın.

MSVC'ye özgü AddressSanitizer çalışma zamanı seçenekleri

  • windows_hook_legacy_allocatorsBoole değeri, ve LocalAlloc ayırıcılarının GlobalAlloc kesilmesini devre dışı bırakmak için olarak ayarlanırfalse.

    Not

    Bu makale yazıldığında bu seçenek windows_hook_legacy_allocators genel llvm-project çalışma zamanında kullanılamamıştı. Seçenek sonunda genel projeye geri katkıda bulunabilir; ancak bu, kod gözden geçirme ve topluluk kabulüne bağlıdır.

    AddressSanitizer deneyselken daha önce bir kabul etme özelliği olan seçeneği windows_hook_rtl_allocatorsartık varsayılan olarak etkindir. Visual Studio 2022 sürüm 17.4.6'nın önceki sürümlerinde varsayılan seçenek değeridir false. Visual Studio 2022 sürüm 17.4.6 ve üzeri sürümlerde, seçenek windows_hook_rtl_allocators varsayılan olarak olur true.

  • iat_overwrite Dize, varsayılan olarak olarak ayarlanır "error" . Diğer olası değerler ve "ignore"şeklindedir"protect". Bazı modüller, belirli işlevlerin import address table uygulamalarını özelleştirmek için diğer modüllerin üzerine yazabilir. Örneğin, sürücüler genellikle belirli donanımlar için özel uygulamalar sağlar. seçeneği, iat_overwrite AddressSanitizer çalışma zamanının belirli memoryapi.h işlevler için üzerine yazma işlemlerine karşı korumasını yönetir. Çalışma zamanı şu anda koruma için , VirtualProtectve VirtualQuery işlevlerini izlerVirtualAlloc. Bu seçenek Visual Studio 2022 sürüm 17.5 Önizleme 1 ve sonraki sürümlerde kullanılabilir. Aşağıdaki iat_overwrite değerler korumalı işlevlerin üzerine yazıldığında çalışma zamanının nasıl tepki göstereceini denetler:

    • (varsayılan) olarak ayarlanırsa "error" , üzerine yazma algılandığında çalışma zamanı bir hata bildirir.
    • olarak ayarlanırsa "protect", çalışma zamanı üzerine yazılan tanımı kullanmaktan kaçınmaya çalışır ve devam eder. İşlevin özgün memoryapi tanımı, sonsuz özyinelemeden kaçınmak için çalışma zamanının içinden etkili bir şekilde kullanılır. İşlemdeki diğer modüller hala üzerine yazılan tanımı kullanır.
    • olarak ayarlanırsa "ignore", çalışma zamanı üzerine yazılan işlevleri düzeltmeye çalışmaz ve yürütmeye devam eder.
  • windows_fast_fail_on_error Boole değeri (varsayılan olarak false), hata raporunu yazdırdıktan sonra işlemin bir __fastfail(71) ile sonlandırılabilmesi için olarak ayarlanır true .

Not

abort_on_error değeri true olarak ayarlandığında, Windows'ta program bir çıkışla (3) sonlandırılır. Geçerli davranışı değiştirmemek için bunun yerine bu yeni seçeneği eklemeye karar verdik. Hem abort_on_error hem de windows_fast_fail_on_error doğruysa, program __fastfail ile çıkar.

Kesişen işlevlerin AddressSanitizer listesi (Windows)

AddressSanitizer çalışma zamanı, çalışma zamanında bellek güvenliği denetimlerini etkinleştirmek için birçok işlevi etkinleştirir. AddressSanitizer çalışma zamanının izlediği işlevlerin kapsamlı olmayan bir listesi aşağıdadır.

Varsayılan kesme çizgileri

İsteğe bağlı kesme çizgileri

Burada listelenen kesme noktaları yalnızca bir AddressSanitizer çalışma zamanı seçeneği etkinleştirildiğinde yüklenir. false Eski ayırıcı kesmeyi devre dışı bırakmak için olarak ayarlayınwindows_hook_legacy_allocators. set ASAN_OPTIONS=windows_hook_legacy_allocators=false

Ayrıca bkz.

AddressSanitizer'a genel bakış
AddressSanitizer bilinen sorunları
AddressSanitizer derlemesi ve dil 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