Hata: stack-use-after-return
Adres Temizleme Hatası: Dönüş sonrasında yığın belleği kullanımı
Bu denetim, /fsanitize-address-use-after-return
ek bir derleyici seçeneği tarafından ve ortam değişkeni ASAN_OPTIONS=detect_stack_use_after_return=1
ayarlanarak etkinleştirilen kod oluşturmayı gerektirir.
Bu denetim uygulamanızı önemli ölçüde yavaşlatabilir. Geri dönüş sonrasında kullanımı destekleyen algoritmanın Clang özetini ve daha yüksek performans maliyetlerini göz önünde bulundurun.
Önemli
Ek derleyici seçeneğini /fsanitize-address-use-after-return
kullanarak bir nesne dosyası oluşturursanız, derleyici tarafından oluşturulan kod bir yığın çerçevesinin nasıl ayrılacağı konusunda çalışma zamanı kararı verir. Ortam değişkeni ASAN_OPTIONS
olarak detect_stack_use_after_return
ayarlı değilse, kod yine de kendi başına kullanmaktan /fsanitize=address
daha yavaştır. Kullanarak alloca()
bir çerçevenin bölümleri için alan ayıran bazı yığın çerçevelerinin ek yükü olduğundan daha yavaştır. Dönüş sonrası kullanım hatalarını işlemeyi bitirdiğinizde bu nesne dosyalarını silmek en iyisidir.
Örnek - Basit C
// example1.cpp
// stack-use-after-return error
volatile char* x;
void foo() {
char stack_buffer[42];
x = &stack_buffer[13];
}
int main() {
foo();
*x = 42; // Boom!
return (*x == 42);
}
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 /fsanitize-address-use-after-return /Zi
set ASAN_OPTIONS=detect_stack_use_after_return=1
devenv /debugexe example1.exe
Sonuç hatası - Basit C
Örnek - C++ ve şablonlar
// example2.cpp
// stack-use-after-return error
#include <stdlib.h>
enum ReadOrWrite { Read = 0, Write = 1 };
struct S32 {
char x[32];
};
template<class T>
T* LeakStack() {
T t[100];
static volatile T* x;
x = &t[0];
return (T*)x;
}
template<class T>
void StackUseAfterReturn(int Idx, ReadOrWrite w) {
static T sink;
T* t = LeakStack<T>();
if (w)
t[100 + Idx] = T();
else
sink = t[100 + Idx];
}
int main(int argc, char* argv[]) {
if (argc != 2) return 1;
int kind = atoi(argv[1]);
switch (kind) {
case 1: StackUseAfterReturn<char>(0, Read); break;
case 2: StackUseAfterReturn<S32>(0, Write); break;
}
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 example2.cpp /fsanitize=address /fsanitize-address-use-after-return /Zi /Od
set ASAN_OPTIONS=detect_stack_use_after_return=1
devenv /debugexe example2.exe 1
ASAN bir dinamik analiz biçimidir, yani yalnızca gerçekte yürütülen hatalı kodu algılayabilir. İyileştirici, veya sink
değerinin t[100 + Idx]
hiçbir zaman kullanılmadığını belirleyebilir ve atamayı ilerletebilir. Sonuç olarak, bu örnek bayrağı gerektirir /Od
.
Sonuç hatası - C++ ve şablonlar
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