Aracılığıyla paylaş


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ı allocave 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, /O2 /GLve profil destekli iyileştirme) uyumludur. Bu seçenekle oluşturulan kod statik ve dinamik CRT'lerle (örneğin, /MD, /MDd, /MTve /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.

Ç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:

ile /fsanitize=fuzzerkullanmanızı /fsanitize=address öneririz.

Bu kitaplıklar, belirttiğinizde /fsanitize=fuzzervarsayı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:

  1. seçeneğini kullanarak /fsanitize-address-use-after-return derleyin.
  2. 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 i386x86_64normal ve x86x64 ş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 /MTdsü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=0geliş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