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=address
derlenirken, 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
/MD
ve /MDd
derleyici seçenekleri için /MT
dil çalışma zamanı kitaplıklarının nasıl bağlanıyor olduğu gösterilmektedir:
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:
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 /MDd
sü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:
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
,delete
HeapFree
/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_allocators
Boole değeri, veLocalAlloc
ayırıcılarınınGlobalAlloc
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_allocators
artı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ğeridirfalse
. Visual Studio 2022 sürüm 17.4.6 ve üzeri sürümlerde, seçenekwindows_hook_rtl_allocators
varsayılan olarak olurtrue
.iat_overwrite
Dize, varsayılan olarak olarak ayarlanır"error"
. Diğer olası değerler ve"ignore"
şeklindedir"protect"
. Bazı modüller, belirli işlevlerinimport 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 belirlimemoryapi.h
işlevler için üzerine yazma işlemlerine karşı korumasını yönetir. Çalışma zamanı şu anda koruma için ,VirtualProtect
veVirtualQuery
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ğıdakiiat_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ünmemoryapi
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.
- (varsayılan) olarak ayarlanırsa
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ırtrue
.
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
__C_specific_handler
(yalnızca x64)_aligned_free
_aligned_malloc
_aligned_msize
_aligned_realloc
_calloc_base
_calloc_crt
_calloc_dbg
(yalnızca hata ayıklama çalışma zamanı)_except_handler3
(yalnızca x86)_except_handler4
(yalnızca x86) (belgelenmemiş)_expand
_expand_base
(belgelenmemiş)_expand_dbg
(yalnızca hata ayıklama çalışma zamanı)_free_base
(belgelenmemiş)_free_dbg
(yalnızca hata ayıklama çalışma zamanı)_malloc_base
(belgelenmemiş)_malloc_crt
(belgelenmemiş)_malloc_dbg
(yalnızca hata ayıklama çalışma zamanı)_msize
_msize_base
(belgelenmemiş)_msize_dbg
(yalnızca hata ayıklama çalışma zamanı)_realloc_base
(belgelenmemiş)_realloc_crt
(belgelenmemiş)_realloc_dbg
(yalnızca hata ayıklama çalışma zamanı)_recalloc
_recalloc_base
(belgelenmemiş)_recalloc_crt
(belgelenmemiş)_recalloc_dbg
(yalnızca hata ayıklama çalışma zamanı)_strdup
atoi
atol
calloc
CreateThread
free
frexp
longjmp
malloc
memchr
memcmp
memcpy
memmove
memset
RaiseException
realloc
RtlAllocateHeap
RtlCreateHeap
RtlDestroyHeap
RtlFreeHeap
RtlRaiseException
RtlReAllocateHeap
(belgelenmemiş)RtlSizeHeap
(belgelenmemiş)SetUnhandledExceptionFilter
strcat
strchr
strcmp
strcpy
strcspn
strdup
strlen
strncat
strncmp
strncpy
strnlen
strpbrk
strspn
strstr
strtok
strtol
wcslen
wcsnlen
İ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
GlobalAlloc
GlobalFree
GlobalHandle
GlobalLock
GlobalReAlloc
GlobalSize
GlobalUnlock
LocalAlloc
LocalFree
LocalHandle
LocalLock
LocalReAlloc
LocalSize
LocalUnlock
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