Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Error:
Error addressSanitizer: uso de la memoria de pila después de la devolución
Observaciones
Esta comprobación requiere la generación del código que se activa por una opción del compilador adicional, /fsanitize-address-use-after-return y estableciendo la variable de entorno ASAN_OPTIONS=detect_stack_use_after_return=1.
Esta comprobación puede ralentizar considerablemente la aplicación. Considere el resumen de Clang del algoritmo que admite el uso después de la devolución y los mayores costos de rendimiento.
Importante
Si crea un archivo de objeto mediante la opción del compilador /fsanitize-address-use-after-return adicional, el código generado por el compilador toma una decisión en tiempo de ejecución sobre cómo asignar un marco de pila. Si la variable de entorno ASAN_OPTIONS no está establecida en detect_stack_use_after_return, el código sigue siendo más lento que al usarse /fsanitize=address por sí mismo. Es más lento porque todavía hay sobrecarga adicional de algunos marcos de pila que asignan espacio para las partes de un marco mediante alloca(). Es mejor eliminar estos archivos de objeto cuando haya terminado de procesar los errores de uso después de la devolución.
Ejemplo: C simple
// 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);
}
Para compilar y probar este ejemplo, ejecute estos comandos en un símbolo del sistema para desarrolladores de Visual Studio 2019 versión 16.9 o posterior:
cl example1.cpp /fsanitize=address /fsanitize-address-use-after-return /Zi
set ASAN_OPTIONS=detect_stack_use_after_return=1
devenv /debugexe example1.exe
Error resultante: C simple
Ejemplo: C++ y plantillas
// 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;
}
Para compilar y probar este ejemplo, ejecute estos comandos en un símbolo del sistema para desarrolladores de Visual Studio 2019 versión 16.9 o posterior:
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 es una forma de análisis dinámico, lo que significa que solo puede detectar código incorrecto que realmente se ejecuta. Un optimizador puede determinar que el valor de t[100 + Idx] o sink nunca se usa y se ha elide de la asignación. Como resultado, este ejemplo requiere la /Od marca .
Error resultante: C++ y plantillas
Consulte también
Introducción a AddressSanitizer
Problemas conocidos de AddressSanitizer
Referencia de lenguaje y compilación de AddressSanitizer
Referencia del entorno de ejecución addressSanitizer
Bytes de sombra addressSanitizer
Pruebas distribuidas o en la nube addressSanitizer
Integración del depurador AddressSanitizer
Ejemplos de errores addressSanitizer