Hata: global-buffer-overflow
Adres Temizleme Hatası: Genel arabellek taşması
Derleyici, veya .bss
bölümlerindeki .data
herhangi bir değişken için meta veriler oluşturur. Bu değişkenlerin dil kapsamı genel veya dosya statiktir. Bunlar başlamadan önce main()
bellekte ayrılır. C'deki genel değişkenler C++ dilinden çok farklı şekilde değerlendirilir. Bu farkın nedeni C'yi bağlamaya yönelik karmaşık kurallardır.
C'de, genel değişken birkaç kaynak dosyada bildirilebilir ve her tanımın farklı türleri olabilir. Derleyici tüm olası tanımları aynı anda göremez, ancak bağlayıcı görebilir. C için bağlayıcı varsayılan olarak tüm farklı bildirimler arasından en büyük boyutlu değişkeni seçer.
C++ dilinde, derleyici tarafından bir genel ayrılır. Yalnızca bir tanım olabileceğinden, her tanımın boyutu derleme zamanında bilinir.
Örnek - 'C' dilinde birden çok tür tanımına sahip geneller
// file: a.c
int x;
// file: b.c
char* x;
// file: c.c
float* x[3];
// file: example1-main.c
// global-buffer-overflow error
// AddressSanitizer reports a buffer overflow at the first line
// in function main() in all cases, REGARDLESS of the order in
// which the object files: a.obj, b.obj, and c.obj are linked.
double x[5];
int main() {
int rc = (int) x[5]; // Boom!
return rc;
}
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 a.c b.c c.c example1-main.c /fsanitize=address /Zi
devenv /debugexe example1-main.exe
Sonuçta oluşan hata
Örnek - basit işlev düzeyi statik
// example2.cpp
// global-buffer-overflow error
#include <string.h>
int
main(int argc, char **argv) {
static char XXX[10];
static char YYY[10];
static char ZZZ[10];
memset(XXX, 0, 10); memset(YYY, 0, 10); memset(ZZZ, 0, 10);
int res = YYY[argc * 10]; // Boom!
res += XXX[argc] + ZZZ[argc];
return res;
}
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ı - basit işlev düzeyi statik
Örnek - C++ içindeki tüm genel kapsamlar
// example3.cpp
// global-buffer-overflow error
// Run 4 different ways with the choice of one of these options:
//
// -g : Global
// -c : File static
// -f : Function static
// -l : String literal
#include <string.h>
struct C {
static int array[10];
};
// normal global
int global[10];
// class static
int C::array[10];
int main(int argc, char **argv) {
int one = argc - 1;
switch (argv[1][1]) {
case 'g': return global[one * 11]; //Boom! simple global
case 'c': return C::array[one * 11]; //Boom! class static
case 'f':
{
static int array[10] = {};
return array[one * 11]; //Boom! function static
}
case 'l':
// literal global ptr created by compiler
const char *str = "0123456789";
return str[one * 11]; //Boom! .rdata string literal allocated by compiler
}
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
devenv /debugexe example3.exe -l
Sonuç hatası - C++ içindeki tüm genel kapsamlar
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