AddressSanitizer dili, derleme ve hata ayıklama başvurusu
Bu makaledeki bölümlerde AddressSanitizer dil belirtimi, derleyici seçenekleri ve bağlayıcı seçenekleri açıklanmaktadır. Ayrıca, AddressSanitizer'a özgü Visual Studio hata ayıklayıcısı tümleştirmesini denetleye seçenekleri de açıklar.
AddressSanitizer çalışma zamanı hakkında daha fazla bilgi için çalışma zamanı başvurusuna bakın. Kesişen işlevler ve özel ayırıcıları bağlama hakkında bilgi içerir. AddressSanitizer hatalarından kilitlenme dökümlerini kaydetme hakkında daha fazla bilgi için kilitlenme dökümü başvurusuna bakın.
Dil belirtimi
__SANITIZE_ADDRESS__
Önişlemci __SANITIZE_ADDRESS__
makro, ayarlandığı zaman /fsanitize=address
olarak 1
tanımlanır. Bu makro, ileri düzey kullanıcıların AddressSanitizer çalışma zamanının varlığı için kaynak kodunu koşullu olarak belirtmesi için yararlıdır.
#include <cstdio>
int main() {
#ifdef __SANITIZE_ADDRESS__
printf("Address sanitizer enabled");
#else
printf("Address sanitizer not enabled");
#endif
return 1;
}
__declspec(no_sanitize_address)
Tanımlayıcı __declspec(no_sanitize_address)
, işlevler, yerel değişkenler veya genel değişkenler üzerinde dezenfektanı seçmeli olarak devre dışı bırakmak için kullanılabilir. Bu__declspec
, çalışma zamanı davranışını değil derleyici davranışını etkiler.
__declspec(no_sanitize_address)
void test1() {
int x[100];
x[100] = 5; // ASan exception not caught
}
void test2() {
__declspec(no_sanitize_address) int x[100];
x[100] = 5; // ASan exception not caught
}
__declspec(no_sanitize_address) int g[100];
void test3() {
g[100] = 5; // ASan exception not caught
}
Derleyici
/fsanitize=address
derleyici seçeneği
Derleyici /fsanitize=address
seçeneği, çalışma zamanında bellek güvenliği hatalarını yakalamak için kodunuzdaki bellek başvurularını algılar. İzleme yükleri, depoları, kapsamları alloca
ve CRT işlevlerini bağlar. Sınır dışı, kullanım sonrası, kapsam dışında gibi gizli hataları algılayabilir. Çalışma zamanında algılanan hataların tükenmez bir listesi için bkz . AddressSanitizer hata örnekleri.
/fsanitize=address
mevcut tüm C++ veya C iyileştirme düzeyleriyle (örneğin, /Od
, /O1
, /O2
ve /O2 /GL
) uyumludur. Bu seçenekle oluşturulan kod statik ve dinamik CRT'lerle (örneğin, /MD
, /MDd
, /MT
ve /MTd
) çalışır. Bu derleyici seçeneği, x86 veya x64'i hedefleyen bir .EXE veya .DLL oluşturmak için kullanılabilir. Çağrı yığınlarının en iyi biçimlendirmesi için hata ayıklama bilgileri gereklidir. Bu derleyici seçeneği profil destekli iyileştirme ile desteklenmez.
Çeşitli hata algılama türlerini gösteren kod örnekleri için bkz . AddressSanitizer hata örnekleri.
/fsanitize=fuzzer
derleyici seçeneği (deneysel)
Derleyici /fsanitize=fuzzer
seçeneği LibFuzzer'ı varsayılan kitaplık listesine ekler. Ayrıca aşağıdaki dezenfektan kapsamı seçeneklerini de ayarlar:
- Kenar izleme noktaları (
/fsanitize-coverage=edge
), - satır içi 8 bit sayaçlar (
/fsanitize-coverage=inline-8bit-counters
), - karşılaştırmalar (
/fsanitize-coverage=trace-cmp
)ve - tamsayı bölmeleri (
/fsanitize-coverage=trace-div
).
ile /fsanitize=fuzzer
kullanmanızı /fsanitize=address
öneririz.
Bu kitaplıklar, belirttiğinizde /fsanitize=fuzzer
varsayılan kitaplık listesine eklenir:
Çalışma zamanı seçeneği | LibFuzzer kütüphanesi |
---|---|
/MT |
clang_rt.fuzzer_MT-{arch} |
/MD |
clang_rt.fuzzer_MD-{arch} |
/MTd |
clang_rt.fuzzer_MTd-{arch} |
/MDd |
clang_rt.fuzzer_MDd-{arch} |
İşlevi atlayan main
LibFuzzer kitaplıkları da kullanılabilir. Bu kitaplıkları ne zaman ve ne zaman kullanacağınızı tanımlamak main
ve LLVMFuzzerTestOneInput
çağırmak LLVMFuzzerInitialize
sizin sorumluluğunuzdadır. Bu kitaplıklardan birini kullanmak için, çalışma zamanınıza ve mimarinize karşılık gelen aşağıdaki kitaplıkla açıkça bağlantı belirtin /NODEFAULTLIB
ve bağlayın:
Çalışma zamanı seçeneği | LibFuzzer no_main kitaplığı |
---|---|
/MT |
clang_rt.fuzzer_no_main_MT-{arch} |
/MD |
clang_rt.fuzzer_no_main_MD-{arch} |
/MTd |
clang_rt.fuzzer_no_main_MTd-{arch} |
/MDd |
clang_rt.fuzzer_no_main_MDd-{arch} |
Belirtirseniz /NODEFAULTLIB
ve bu kitaplıklardan birini belirtmezseniz, çözülmemiş bir dış simge bağlantısı hatası alırsınız.
/fsanitize-address-use-after-return
derleyici seçeneği (deneysel)
Varsayılan olarak, MSVC derleyicisi (Clang'den farklı olarak) dönüş sonrası kullanım hatalarını yakalamak için yığındaki çerçeveleri ayırmak için kod oluşturmaz. AddressSanitizer kullanarak bu hataları yakalamak için şunlar gerekir:
- seçeneğini kullanarak
/fsanitize-address-use-after-return
derleyin. - Programınızı yürütmeden önce, çalışma zamanı onay seçeneğini ayarlamak için komutunu çalıştırın
set ASAN_OPTIONS=detect_stack_use_after_return=1
.
seçeneği, /fsanitize-address-use-after-return
yerel öğeler "adres alındı" olarak kabul edildiğinde derleyicinin yığında çift yığın çerçevesi kullanacak bir kod oluşturmasına neden olur. Bu kod yalnızca tek başına kullanmaktan /fsanitize=address
çok daha yavaştır. Daha fazla bilgi ve örnek için bkz . Hata: stack-use-after-return
.
Yığındaki çift yığın çerçevesi, onu oluşturan işlevden geri dönüşten sonra kalır. Dönüş sonrasında yığındaki bir yuvaya ayrılan yerel bir adresin kullanıldığı bir örneği düşünün. Sahte yığın çerçevesiyle ilişkili gölge baytlar 0xF9 değerini içerir. Bu 0xF9, çalışma zamanı hatayı bildirdiğinde stack-use-after-return hatası anlamına gelir.
Yığın çerçeveleri yığında ayrılır ve işlevler döndürdükten sonra kalır. Çalışma zamanı, belirli bir zaman aralığından sonra bu sahte çağrı çerçevesi nesnelerini zaman uyumsuz olarak boşaltmak için çöp toplamayı kullanır. Yerellerin adresleri yığındaki kalıcı çerçevelere aktarılır. Tanımlama işlevi döndürdüğünde sistem herhangi bir yerelin ne zaman kullanıldığını nasıl algılayabilir. Daha fazla bilgi için Bkz . Google tarafından belgelendiği gibi geri döndükten sonra yığın kullanımı algoritması.
Bağlayıcı
/INFERASANLIBS[:NO]
bağlayıcı seçeneği
Derleyici /fsanitize=address
seçeneği, yürütülebilir dosyanıza hangi AddressSanitizer kitaplığının bağlanacağını belirtmek için nesneleri işaretler. Kitaplıkların ile clang_rt.asan*
başlayan adları vardır. /INFERASANLIBS
Bağlayıcı seçeneği (varsayılan olarak açık) bu kitaplıkları varsayılan konumlarından otomatik olarak bağlar. Burada, seçilen ve otomatik olarak bağlanan kitaplıklar yer alır.
Not
Aşağıdaki tabloda {arch}
veya x86_64
şeklindediri386
.
Bu kitaplıklar mimari adları için Clang kurallarını kullanır. MSVC kuralları ve yerine i386
x86_64
normal ve x86
x64
şeklindedir. Bunlar 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} |
Bağlayıcı seçeneği /INFERASANLIBS:NO
, bağlayıcının bir kitaplık dosyasını varsayılan konumdan bağlamasını clang_rt.asan*
engeller. Bu seçeneği kullanırsanız derleme betiklerinize kitaplık yolunu ekleyin. Aksi takdirde bağlayıcı çözülmemiş bir dış simge hatası bildirir.
Önceki Sürümler
Visual Studio 17.7 Preview 3'e başlamadan ö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. Ayrıca, dinamik olarak bağlı projeler (/MD
veya ) projenin hata ayıklama veya /MTd
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.
CRT çalışma zamanı seçeneği | DLL veya EXE | AddressSanitizer çalışma zamanı kitaplıkları |
---|---|---|
/MT |
EXE | clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
/MT |
DLL | clang_rt.asan_dll_thunk-{arch} |
/MD |
Herhangi biri | clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
/MTd |
EXE | clang_rt.asan_dbg-{arch} , clang_rt.asan_dbg_cxx-{arch} |
/MTd |
DLL | clang_rt.asan_dbg_dll_thunk-{arch} |
/MDd |
Herhangi biri | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
Visual Studio ile tümleştirme
/fno-sanitize-address-vcasan-lib
derleyici seçeneği
Seçenek, /fsanitize=address
bir AddressSanitizer özel durumu oluştuğunda geliştirilmiş bir Visual Studio hata ayıklama deneyimi için ek kitaplıklara bağlanır. Bu kitaplıklara VCAsan adı verilir. Kitaplıklar, Visual Studio'nun kaynak kodunuzda AddressSanitizer hatalarını görüntülemesini sağlar. Ayrıca, bir AddressSanitizer hata raporu oluşturulduğunda yürütülebilir dosyanın kilitlenme dökümleri oluşturmasını sağlar. Daha fazla bilgi için bkz . Visual Studio AddressSanitizer genişletilmiş işlevsellik kitaplığı.
Seçilen kitaplık derleyici seçeneklerine bağlıdır ve otomatik olarak bağlanır.
Çalışma zamanı seçeneği | VCAsan sürümü |
---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
Ancak, kullanarak /Zl
derlerseniz (Varsayılan kitaplık adını atla), kitaplığı el ile belirtmeniz gerekir. Aksi takdirde çözülmemiş bir dış simge bağlantısı hatası alırsınız. Bazı tipik örnekleri aşağıda bulabilirsiniz:
error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib
Geliştirilmiş hata ayıklama, derleme zamanında seçeneği kullanılarak /fno-sanitize-address-vcasan-lib
devre dışı bırakılabilir.
ASAN_VCASAN_DEBUGGING
ortam değişkeni
Derleyici seçeneği, /fsanitize=address
çalışma zamanında bellek güvenliği hatalarını kullanıma sunan bir ikili oluşturur. İkili komut satırından başlatıldığında ve çalışma zamanı bir hata bildirdiğinde, hata ayrıntılarını yazdırır. Ardından işlemden çıkar. Ortam değişkeni, ASAN_VCASAN_DEBUGGING
çalışma zamanı bir hata bildirdiğinde Visual Studio IDE'yi hemen başlatacak şekilde ayarlanabilir. Bu derleyici seçeneği, hataya neden olan tam satır ve sütunda kaynak kodunuzun üzerine gelen hatayı görüntülemenizi sağlar.
Bu davranışı etkinleştirmek için, uygulamanızı çalıştırmadan önce komutunu set ASAN_VCASAN_DEBUGGING=1
çalıştırın. komutunu çalıştırarak set ASAN_VCASAN_DEBUGGING=0
gelişmiş hata ayıklama deneyimini devre dışı bırakabilirsiniz.
Ayrıca bkz.
AddressSanitizer'a genel bakış
AddressSanitizer bilinen sorunları
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