Referencia de lenguaje AddressSanitizer, compilación y depuración
En las secciones de este artículo se describen la especificación del lenguaje AddressSanitizer, las opciones del compilador y las opciones del vinculador. También describen las opciones que controlan la integración Visual Studio depurador específica de AddressSanitizer.
Para obtener más información sobre el entorno de ejecución AddressSanitizer, consulte la referencia del entorno de ejecución. Incluye información sobre las funciones interceptadas y cómo enlazar asignadores personalizados. Para obtener más información sobre cómo guardar volcados de memoria de errores addressSanitizer, consulte la referencia de volcado de memoria.
Especificación del lenguaje
__SANITIZE_ADDRESS__
La __SANITIZE_ADDRESS__ macro de preprocesador se define como cuando 1 se establece /fsanitize=address . Esta macro es útil para que los usuarios avanzados especifiquen condicionalmente el código fuente para la presencia del tiempo de ejecución AddressSanitizer.
#include <cstdio>
int main() {
#ifdef __SANITIZE_ADDRESS__
printf("Address sanitizer enabled");
#else
printf("Address sanitizer not enabled");
#endif
return 1;
}
__declspec(no_sanitize_address)
El especificador se puede usar para deshabilitar de forma selectiva el __declspec(no_sanitize_address) sanitizador en funciones, variables locales o variables globales. Esto __declspec afecta al comportamiento del __declspec no al comportamiento en tiempo de ejecución.
__declspec(no_sanitize_address)
void test1() {
int x[100];
x[100] = 5; // ASan exception not caught
}
void test2() {
__declspec(no_sanitize_address) int x[100];
x[100] = 5; // ASan exception not caught
}
__declspec(no_sanitize_address) int g[100];
void test3() {
g[100] = 5; // ASan exception not caught
}
Compilador
Opción del compilador /fsanitize=address
La /fsanitize=address opción del compilador instrumentala las referencias de memoria en el código para detectar errores de seguridad de memoria en tiempo de ejecución. La instrumentación conecta las funciones de carga, almacenes, alloca ámbitos, y CRT. Puede detectar errores ocultos, como fuera de límites, uso después de liberar, uso después del ámbito, y así sucesivamente. Para obtener una lista no exhaustiva de los errores detectados en tiempo de ejecución, vea Ejemplos de errores addressSanitizer.
/fsanitize=address es compatible con todos los niveles de optimización de C++ o C existentes (por ejemplo, , , , y la optimización guiada /Od por /O1/O2/O2 /GL perfiles). El código generado con esta opción funciona con CRT estáticos y dinámicos (por ejemplo, /MD , /MDd , y /MT/MTd ). Esta opción del compilador se puede usar para crear un .EXE o .DLL para x86 o x64. La información de depuración es necesaria para un formato óptimo de las pilas de llamadas.
Para obtener ejemplos de código que muestra varios tipos de detección de errores, vea Ejemplos de errores addressSanitizer.
/fsanitize=fuzzer opción del compilador (experimental)
La /fsanitize=fuzzer opción del compilador agrega /fsanitize=fuzzer la lista de bibliotecas predeterminada. También establece las siguientes opciones de cobertura de sanitizador:
- Puntos de instrumentación perimetral ( ),
- contadores de 8 bits en línea ( ),
- comparaciones ( )y
- divisiones de enteros ( ).
Se recomienda usar /fsanitize=address con /fsanitize=fuzzer .
Estas bibliotecas se agregan a la lista de bibliotecas predeterminada cuando se especifica /fsanitize=fuzzer :
| Opción runtime | Biblioteca LibFuzzer |
|---|---|
/MT |
clang_rt.fuzzer_MT-{arch} |
/MD |
clang_rt.fuzzer_MD-{arch} |
/MTd |
clang_rt.fuzzer_MTd-{arch} |
/MDd |
clang_rt.fuzzer_MDd-{arch} |
También están disponibles las bibliotecas de LibFuzzer que main omiten la función. Es su responsabilidad definir y main llamar a y cuando use estas LLVMFuzzerInitializeLLVMFuzzerTestOneInput bibliotecas. Para usar una de estas bibliotecas, especifique y vincule explícitamente con la biblioteca siguiente que corresponda a su entorno /NODEFAULTLIB de ejecución y arquitectura:
| Opción runtime | Biblioteca de no_main LibFuzzer |
|---|---|
/MT |
clang_rt.fuzzer_no_main_MT-{arch} |
/MD |
clang_rt.fuzzer_no_main_MD-{arch} |
/MTd |
clang_rt.fuzzer_no_main_MTd-{arch} |
/MDd |
clang_rt.fuzzer_no_main_MDd-{arch} |
Si especifica y no especifica una de estas bibliotecas, se producirá un error de vínculo de símbolo /NODEFAULTLIB externo sin resolver.
/fsanitize-address-use-after-return opción del compilador (experimental)
De forma predeterminada, MSVC compilador (a diferencia de Clang) no genera código para asignar fotogramas en el montón para detectar errores de uso después de la devolución. Para detectar estos errores mediante AddressSanitizer, debe:
- Compile con la
/fsanitize-address-use-after-returnopción . - Antes de ejecutar el programa, ejecute para
set ASAN_OPTIONS=detect_stack_use_after_return=1establecer la opción de comprobación en tiempo de ejecución.
La opción hace que el compilador genere código para usar un marco de pila dual en el montón cuando las locales se /fsanitize-address-use-after-return consideran "direcciones tomadas". Este código es mucho más lento que usar solo. Para obtener más información y un ejemplo, vea Error: .
El marco de pila dual del montón permanece después de la devolución de la función que lo creó. Considere un ejemplo en el que la dirección de un local, asignada a una ranura del montón, se usa después de la devolución. Los bytes de sombra asociados al marco de montón falso contienen el valor 0xF9. Esto 0xF9 significa un error stack-use-after-return cuando el tiempo de ejecución notifica el error.
Los marcos de pila se asignan en el montón y permanecen después de que se devuelvan las funciones. El tiempo de ejecución usa la recolección de elementos no utilizados para liberar de forma asincrónica estos objetos de marco de llamadas falsos, después de un intervalo de tiempo determinado. Las direcciones de las locales se transfieren a fotogramas persistentes en el montón. Es la forma en que el sistema puede detectar cuándo se usan las locales después de que se devuelva la función de definición. Para obtener más información, consulte el algoritmo para el uso de la pila después de la devolución, como se documenta en Google.
Enlazador
/INFERASANLIBS[:NO] opción del vinculador
La /fsanitize=address opción del compilador marca los objetos para especificar la biblioteca AddressSanitizer que se vinculará al archivo ejecutable. Las bibliotecas tienen nombres que comienzan por clang_rt.asan* . La /INFERASANLIBS opción del vinculador (activa de forma predeterminada) vincula automáticamente estas bibliotecas desde sus ubicaciones predeterminadas. Estas son las bibliotecas elegidas y vinculadas automáticamente en:
| Opción runtime | DLL o EXE | Bibliotecas en tiempo de ejecución addressSanitizer |
|---|---|---|
/MT |
EXE | clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch} |
/MT |
Archivo DLL | clang_rt.asan_dll_thunk-{arch} |
/MD |
YA SEA | clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} |
/MTd |
EXE | clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch} |
/MTd |
Archivo DLL | clang_rt.asan_dbg_dll_thunk-{arch} |
/MDd |
YA SEA | clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
La opción del vinculador /INFERASANLIBS:NO impide que el vinculador vincule un archivo clang_rt.asan* de biblioteca desde la ubicación predeterminada. Agregue la ruta de acceso de la biblioteca en los scripts de compilación si usa esta opción. De lo contrario, el vinculador notifica un error de símbolo externo sin resolver.
integración de Visual Studio
Opción del compilador /fno-sanitize-address-vcasan-lib
La opción vincula en bibliotecas adicionales para mejorar Visual Studio de depuración cuando se produce una /fsanitize=address excepción AddressSanitizer. Estas bibliotecas se denominan VCAsan. Las bibliotecas permiten Visual Studio mostrar los errores addressSanitizer en el código fuente. También permiten que el ejecutable genere volcados de memoria cuando se crea un informe de errores AddressSanitizer. Para obtener más información, vea Visual Studio biblioteca de funcionalidades extendidas AddressSanitizer.
La biblioteca elegida depende de las opciones del compilador y se vincula automáticamente.
| Opción runtime | Versión de VCAsan |
|---|---|
/MT |
libvcasan.lib |
/MD |
vcasan.lib |
/MTd |
libvcasand.lib |
/MDd |
vcasand.lib |
Sin embargo, si compila con (Omitir nombre de biblioteca predeterminado), deberá /Zl especificar manualmente la biblioteca. Si no lo hace, se producirá un error de vínculo de símbolo externo sin resolver. Estos son algunos ejemplos típicos:
error LNK2001: unresolved external symbol __you_must_link_with_VCAsan_lib
error LNK2001: unresolved external symbol ___you_must_link_with_VCAsan_lib
La depuración mejorada se puede deshabilitar en tiempo de compilación mediante la /fno-sanitize-address-vcasan-lib opción .
La variable de entorno ASAN_VCASAN_DEBUGGING
La opción del compilador genera un archivo binario que expone errores de seguridad /fsanitize=address de memoria en tiempo de ejecución. Cuando el archivo binario se inicia desde la línea de comandos y el tiempo de ejecución notifica un error, imprime los detalles del error. A continuación, sale del proceso. La ASAN_VCASAN_DEBUGGING variable de entorno se puede establecer para iniciar el IDE Visual Studio inmediatamente cuando el tiempo de ejecución informa de un error. Esta opción del compilador permite ver el error, superpuesto sobre el código fuente, en la línea y columna precisas que provocaron el error.
Para habilitar este comportamiento, ejecute el comando set ASAN_VCASAN_DEBUGGING=1 antes de ejecutar la aplicación. Puede deshabilitar la experiencia de depuración mejorada mediante la ejecución de set ASAN_VCASAN_DEBUGGING=0 .
Vea también
Información general de AddressSanitizer
Problemas conocidos de AddressSanitizer
Referencia del entorno de ejecución de AddressSanitizer
Bytes paralelos de AddressSanitizer
Nube o pruebas distribuidas de AddressSanitizer
Integración del depurador de AddressSanitizer
Ejemplos de errores de AddressSanitizer