AddressSanitizer
Información general
Los lenguajes C++ son eficaces, pero pueden sufrir una clase de errores que afectan a la corrección del programa y & a la seguridad del programa. A partir Visual Studio versión 16.9 de 2019, el compilador de Microsoft C/C++ (MSVC) y el IDE admiten AddressSanitizer. AddressSanitizer (ASan) es una tecnología de compilador y tiempo de ejecución que expone muchos errores difíciles de encontrar con cero falsos positivos:
- Errores de coincidencia de asign/desasignación
deletey tipos no coincidentes - Asignaciones demasiado grandes para el montón
- desbordamiento y desbordamiento
- Doble gratis yuso después de gratis
- Desbordamiento de variable global
- Desbordamiento de búfer de montón
- Alineación no válida de valores alineados
memcpysuperposiciónmemcpy- Desbordamiento de búfer de pila y subdesbordamiento
- Uso de pila después y usar después del ámbito
- Uso de memoria después de ser dudoso
Use AddressSanitizer para reducir el tiempo dedicado a:
- Corrección básica
- Portabilidad multiplataforma
- Seguridad
- pruebas de esfuerzo
- Integración de código nuevo
AddressSanitizer, introducido originalmente por Google,es una alternativa eficaz a (comprobaciones de errores en tiempo de ejecución) y (análisis estático). Proporciona tecnologías de búsqueda de errores en tiempo de ejecución que usan directamente los sistemas de compilación existentes y los recursos de prueba existentes.
AddressSanitizer se integra con el Visual Studio proyecto, el sistema de compilación de CMake y el IDE. Los proyectos pueden habilitar AddressSanitizer estableciendo una propiedad de proyecto o usando una opción del compilador adicional: /fsanitize=address . La nueva opción es compatible con todos los niveles de optimización y configuraciones de x86 y x64. Sin embargo, no es compatible con editar y continuar,vincular incrementalmentey .
A partir Visual Studio versión 16.9 de 2019, la tecnología AddressSanitizer de Microsoft permite la integración con Visual Studio IDE. Opcionalmente, la funcionalidad puede crear un archivo de volcado de memoria cuando el sanitizador encuentra un error en tiempo de ejecución. Si establece la variable de entorno antes de ejecutar el programa, se crea un archivo de volcado de memoria con metadatos adicionales para una depuración posterior eficaz de errores con diagnóstico ASAN_SAVE_DUMPS=MyFileName.dmp preciso. ASAN_SAVE_DUMPS=MyFileName.dmp Estos archivos de volcado facilitan el uso extendido de AddressSanitizer para:
- Pruebas de máquinas locales,
- Pruebas distribuidas locales y
- Flujos de trabajo basados en la nube para pruebas.
Instalación de AddressSanitizer
Las bibliotecas y la integración del IDE addressSanitizer se instalan de forma predeterminada con cargas de trabajo de C++ en el Instalador de Visual Studio. Sin embargo, si va a actualizar desde una versión anterior de Visual Studio 2019, use el instalador para habilitar la compatibilidad con ASan después de la actualización:
Puede elegir Modificar en la instalación de Visual Studio existente en Instalador de Visual Studio para llegar a la pantalla anterior.
Nota
Si ejecuta Visual Studio en la nueva actualización pero no ha instalado ASan, se producirá un error al ejecutar el código:
LNK1356: no se encuentra la biblioteca "clang_rt.asan_dynamic-i386.lib"
Uso de AddressSanitizer
Comience a compilar los ejecutables con la /fsanitize=address opción del compilador mediante cualquiera de estos métodos de desarrollo comunes:
- Compilaciones de línea de comandos
- Sistema de proyectos de Visual Studio
- Visual Studio integración de CMake
Vuelva a compilar y, a continuación, ejecute el programa con normalidad. Esta generación de código expone muchos tipos de errores con diagnóstico preciso. Estos errores se notifican de tres maneras: en el IDE del depurador, en la línea de comandos o almacenados en un nuevo tipo de archivo de volcado para un procesamiento preciso fuera de línea.
Microsoft recomienda usar AddressSanitizer en estos tres flujos de trabajo estándar:
Bucle interno para desarrolladores
- Visual Studio: línea de comandos
- Visual Studio: Project sistema
- Visual Studio: CMake
CI/CD: integración continua/desarrollo continuo
- Informes de errores: nuevos archivos de volcado addressSanitizer
Fuzzing: creación con el contenedor libFuzzer
- Azure OneFuzz
- Equipo local
En este artículo se trata la información necesaria para habilitar los tres flujos de trabajo enumerados anteriormente. La información es específica de la implementación del Windows 10 dependiente de la plataforma de AddressSanitizer. Esta documentación complementa la excelente documentación de Google, Apple y GCC ya publicada.
Nota
La compatibilidad actual se limita a x86 y x64 en Windows 10. Envíenos sus comentarios sobre lo que le gustaría ver en futuras versiones. Sus comentarios nos ayudan a priorizar otros sanitizadores para el futuro, como /fsanitize=thread , , , o /fsanitize=leak/fsanitize=memory/fsanitize=undefined/fsanitize=hwaddress . Puede notificar errores aquí si tiene problemas.
Uso de AddressSanitizer desde un símbolo del sistema para desarrolladores
Use la opción del compilador en un símbolo del sistema para desarrolladores para habilitar /fsanitize=address la compilación para el tiempo de ejecución addressSanitizer. /fsanitize=address La opción es compatible con todos los niveles de optimización de C++ o /fsanitize=address C existentes (por ejemplo, /Od , , , y /O1/O2/O2 /GLPGO ). La opción funciona con CRT estáticos y dinámicos (por ejemplo, /MD , /MDd , y /MT/MTd ). Funciona tanto si se crea un archivo EXE como un archivo DLL. La información de depuración es necesaria para un formato óptimo de las pilas de llamadas. En el ejemplo siguiente, cl /fsanitize=address /Zi se pasa a la línea de comandos.
Las bibliotecas addressSanitizer (archivos .lib) se vinculan automáticamente. Para obtener más información, vea AddressSanitizer language, build, and debugging reference.
Ejemplo: desbordamiento de búfer global básico
// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
printf("Hello!\n");
x[100] = 5; // Boom!
return 0;
}
Uso de un símbolo del sistema para desarrolladores Visual Studio 2019, compilar main.cpp mediante/fsanitize=address /Zi
Al ejecutar el resultante en la línea de comandos, crea el informe de errores con formato que se main.exe muestra a continuación.
Tenga en cuenta los cuadros rojos superápiles que resaltan siete partes clave de información:
Resaltados rojos, de arriba abajo
- El error de seguridad de memoria es un desbordamiento de búfer global.
- Había 4 bytes (32 bits) almacenados fuera de cualquier variable definida por el usuario.
- El almacén tuvo lugar en la función
main()definida en el archivo de la líneabasic-global-overflow.cpp7. - La variable denominada
xse define en basic-global-overflow.cpp en la línea 3, a partir de la columna 8. - Esta variable global
xtiene un tamaño de 400 bytes. - El byte de sombra exacto que describe la dirección de destino del almacén tenía un valor de
- La leyenda de bytes de sombra indica
0xf9que es un área de relleno a la derecha deint x[100]
Nota
Los nombres de función de la pila de llamadas se generan a través del clasificador LLVM invocado por el tiempo de ejecución en caso de error.
Use addressSanitizer en Visual Studio
AddressSanitizer se integra con Visual Studio IDE. Para activar addressSanitizer para un proyecto MSBuild, haga clic con el botón derecho en el proyecto en Explorador de soluciones elija Propiedades. En el cuadro de diálogo Páginas de propiedades, seleccione Propiedades deconfiguración C/C++General y, a continuación, modifique la propiedad Habilitar AddressSanitizer. Elija Aceptar para guardar los cambios.
Para compilar desde el IDE, opte por no usar ninguna opción incompatible. Para un proyecto existente compilado mediante (o modo de depuración), es posible que /Od tenga que desactivar estas opciones:
- Desactivar la edición y continuar
- Desactivar (comprobaciones en tiempo de ejecución)
- Desactivar (vinculación incremental)
Para compilar y ejecutar el depurador, escriba F5. Verá esta ventana en Visual Studio:
Uso de AddressSanitizer desde Visual Studio: CMake
Para habilitar AddressSanitizer para un proyecto de CMakecreado para el destino Windows , siga estos pasos:
Abra la lista desplegable Configuraciones en la barra de herramientas de la parte superior del IDE y seleccione Administrar configuraciones.
Esa selección abre el editor de Project Configuración CMake, que se guarda en un archivo CMakeSettings.json.
Elija el vínculo Editar JSON en el editor. Esta selección cambia la vista a JSON sin formato.
Agregue la propiedad: "addressSanitizerEnabled": true
Esta imagen es de CMakeSettings.json después de ese cambio:
Escriba Ctrl+S para guardar este archivo JSON y, a continuación, escriba F5 para volver a compilarlo y ejecutarlo en el depurador.
Esta captura de pantalla captura el error de la compilación de CMake.
Volcados de memoria addressSanitizer
Hemos introducido una nueva funcionalidad en AddressSanitizer para su uso con flujos de trabajo distribuidos y en la nube. Esta funcionalidad permite la visualización sin conexión de un error AddressSanitizer en el IDE. El error se sobresalte sobre el origen, tal y como se experimentaría en una sesión de depuración activa.
Estos nuevos archivos de volcado pueden dar lugar a eficiencias al analizar un error. No es necesario volver a ejecutar, buscar datos remotos o buscar una máquina que se ha quedo sin conexión.
Para generar un nuevo tipo de archivo de volcado que se puede ver en Visual Studio en otro equipo en una fecha posterior:
set ASAN_SAVE_DUMPS=MyFileName.dmp
A partir Visual Studio 16.9 puede mostrar un errorcon diagnóstico preciso, almacenado en el archivo, sobre el código fuente.
Esta nueva funcionalidad de volcado de memoria permite flujos de trabajo basados en la nube o pruebas distribuidas. También se puede usar para presentar un error detallado y práctico en cualquier escenario.
Errores de ejemplo
AddressSanitizer puede detectar varios tipos de errores de uso incorrecto de memoria. Estos son muchos de los errores en tiempo de ejecución notificados al ejecutar los archivos binarios compilados mediante la opción del compilador AddressSanitizer ( /fsanitize=address ):
alloc-dealloc-mismatchallocation-size-too-bigcalloc-overflowdouble-freedynamic-stack-buffer-overflowglobal-buffer-overflowheap-buffer-overflowheap-use-after-freeinvalid-allocation-alignmentmemcpy-param-overlapnew-delete-type-mismatchstack-buffer-overflowstack-buffer-underflowstack-use-after-returnstack-use-after-scopestrncat-param-overlapuse-after-poison
Para obtener más información sobre los ejemplos, vea Ejemplos de errores de AddressSanitizer.
Diferencias con Clang 12.0
MSVC difiere actualmente de Clang 12.0 en dos áreas funcionales:
- stack-use-after-scope: esta configuración está activada de forma predeterminada y no se puede desactivar.
- stack-use-after-return: esta funcionalidad requiere una opción del compilador adicional y no está disponible estableciendo solo .
Estas decisiones se tomaron para reducir la matriz de pruebas necesaria para entregar esta primera versión.
No se incluyeron las características que podrían dar lugar a falsos positivos en Visual Studio 16.9 de 2019. Esa materia aplicaba la integridad de prueba eficaz necesaria al considerar la interoperabilidad con décadas de código existente. Se pueden tener en cuenta más funcionalidades en versiones posteriores:
- Fiasco de orden de inicialización
- Desbordamiento de objetos dentro
- Desbordamiento de contenedor
- Comparación o resta de puntero
Para obtener más información, vea Building for the AddressSanitizer with MSVC.
Documentación del sector existente
Ya existe una amplia documentación para estas implementaciones dependientes del lenguaje y la plataforma de la tecnología AddressSanitizer.
En este documento sobre AddressSanitizer se describe la implementación.
Vea también
Problemas conocidos de AddressSanitizer
Referencia de lenguaje y compilación 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