Fehler: global-buffer-overflow
Adressbereinigungsfehler: Globaler Pufferüberlauf
Der Compiler generiert Metadaten für jede Variable in den .data
Abschnitten oder .bss
Abschnitten. Diese Variablen haben den Sprachumfang globaler oder datei statischer Dateien. Sie werden vor dem main()
Start im Arbeitsspeicher zugewiesen. Globale Variablen in C werden viel anders behandelt als in C++. Dieser Unterschied liegt an den komplexen Regeln für die Verknüpfung von C.
In C kann eine globale Variable in mehreren Quelldateien deklariert werden, und jede Definition kann unterschiedliche Typen aufweisen. Der Compiler kann nicht alle möglichen Definitionen gleichzeitig sehen, aber der Linker kann. Bei C wählt der Linker standardmäßig die Variable der größten Größe aus allen verschiedenen Deklarationen aus.
In C++ wird vom Compiler eine globale Zuordnung zugewiesen. Es kann nur eine Definition geben, sodass die Größe jeder Definition zur Kompilierungszeit bekannt ist.
Beispiel : Globalen in "C" mit mehreren Typdefinitionen
// 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;
}
Führen Sie zum Erstellen und Testen dieses Beispiels die folgenden Befehle in einer Visual Studio 2019,16.9- oder höher-Entwickler-Eingabeaufforderung aus:
cl a.c b.c c.c example1-main.c /fsanitize=address /Zi
devenv /debugexe example1-main.exe
Resultierender Fehler
Beispiel : Einfache Funktionsebene statisch
// 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;
}
Führen Sie zum Erstellen und Testen dieses Beispiels die folgenden Befehle in einer Visual Studio 2019,16.9- oder höher-Entwickler-Eingabeaufforderung aus:
cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe
Resultierender Fehler – statische Einfache Funktionsebene
Beispiel : alle globalen Bereiche in C++
// 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;
}
Führen Sie zum Erstellen und Testen dieses Beispiels die folgenden Befehle in einer Visual Studio 2019,16.9- oder höher-Entwickler-Eingabeaufforderung aus:
cl example3.cpp /fsanitize=address /Zi
devenv /debugexe example3.exe -l
Resultierender Fehler – alle globalen Bereiche in C++
Siehe auch
AddressSanitizer -Übersicht
Beheben bekannter Probleme mit demSanitizer
AddressSanitizer Build- und Sprachreferenz
AddressSanitizer-Laufzeitreferenz
AddressSanitizer-Schattenbytes
AddressSanitizer-Cloud oder verteilte Tests
AddressSanitizer Debugger-Integration
Beispiele für AddressSanitizer-Fehler