Aracılığıyla paylaş


Hata: stack-use-after-scope

Adres Temizleme Hatası: Kapsam dışı yığın belleği kullanımı

Bir değişkenin kullanım ömrünün sözcük temelli kapsamının dışında bir yığın adresinin kullanılması C veya C++'da birçok şekilde gerçekleşebilir.

Örnek 1 - basit iç içe yerel

// example1.cpp
// stack-use-after-scope error
int *gp;

bool b = true;

int main() {
    if (b) {
        int x[5];
        gp = x+1;
    }
    return *gp;  // Boom!
}

Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:

cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe

Sonuç hatası - basit iç içe yerel

Örnek 1'de stack-use-after-scope hatasını görüntüleyen hata ayıklayıcının ekran görüntüsü.

Örnek 2 - lambda yakalama

// example2.cpp
// stack-use-after-scope error
#include <functional>

int main() {
    std::function<int()> f;
    {
        int x = 0;
        f = [&x]() {
            return x;  // Boom!
        };
    }
    return f();  // Boom!
}

Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:

cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe

Sonuç hatası - lambda yakalama

Örnek 2'de stack-use-after-scope hatasını görüntüleyen hata ayıklayıcının ekran görüntüsü.

Örnek 3 - yerel ayarlarla yıkıcı sıralaması

// example3.cpp
// stack-use-after-scope error
#include <stdio.h>

struct IntHolder {
    explicit IntHolder(int* val = 0) : val_(val) { }
    ~IntHolder() {
        printf("Value: %d\n", *val_);  // Bom!
    }
    void set(int* val) { val_ = val; }
    int* get() { return val_; }

    int* val_;
};

int main(int argc, char* argv[]) {
    // It's incorrect to use "x" inside the IntHolder destructor,
    // because the lifetime of "x" ends earlier. Per the C++ standard,
    // local lifetimes end in reverse order of declaration.
    IntHolder holder;
    int x = argc;
    holder.set(&x);
    return 0;
}

Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:

cl example3.cpp /fsanitize=address /Zi /O1
devenv /debugexe example3.exe

Sonuçta oluşan hata - yıkıcı sıralama

Örnek 3'te stack-use-after-scope hatasını görüntüleyen hata ayıklayıcının ekran görüntüsü.

Örnek 4 - geçiciler

// example4.cpp
// stack-use-after-scope error
#include <iostream>

struct A {
    A(const int& v) {
        p = &v;
    }
    void print() {
        std::cout << *p;
    }
    const int* p;
};

void explicit_temp() {
    A a(5);     // the temp for 5 is no longer live;
    a.print();
}

void temp_from_conversion() {
    double v = 5;
    A a(v);     // local v is no longer live.
    a.print();
}

void main() {
    explicit_temp();
    temp_from_conversion(); 
}

Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:

cl example4.cpp /EHsc /fsanitize=address /Zi /Od
devenv /debugexe example4.exe

ASAN bir dinamik analiz biçimidir, yani yalnızca gerçekte yürütülen hatalı kodu algılayabilir. İyileştirici, içinde depolanan padresten okumak yerine bu durumlarda değerini v yayabilir. Sonuç olarak, bu örnek bayrağı gerektirir /Od .

Sonuçta oluşan hata - geçiciler

Örnek 4'te stack-use-after-scope hatasını görüntüleyen hata ayıklayıcının ekran görüntüsü.

Ayrıca bkz.

AddressSanitizer'a genel bakış
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