Análisis estático – desde el conocimiento hasta la integración

Cansado de interminables revisiones de código o depuraciones, a veces piensas en cómo simplificar tu vida. Y tras investigar un poco, o por pura casualidad, puedes encontrar la mágica frase: "Análisis estático". Vamos a ver qué es esto y cómo puede interactuar con tu proyecto.

Análisis estático – desde el conocimiento hasta la integración
En realidad, si estás programando en algún lenguaje moderno, probablemente hayas pasado tu código por un analizador estático sin saberlo. Cualquier compilador moderno ofrece, aunque sea un conjunto mínimo, advertencias sobre problemas potenciales en el código. Por ejemplo, al compilar código C++ en Visual Studio, puedes ver lo siguiente:

Análisis estático – desde el conocimiento hasta la integración
En esta salida, vemos que la variable var no se ha utilizado en ninguna parte de la función. Así que, de hecho, casi siempre has estado usando un simple analizador estático de código. Sin embargo, a diferencia de los analizadores profesionales como Coverity, Klocwork o PVS-Studio, las advertencias proporcionadas por el compilador pueden señalar solo un pequeño espectro de problemas.

Si no sabes con certeza qué es el análisis estático y cómo implementarlo, este artículo, para familiarizarte más con esta metodología.

¿Para qué sirve el análisis estático?

En pocas palabras: agiliza y simplifica.

El análisis estático permite encontrar una gran cantidad de problemas en el código: desde un uso incorrecto de construcciones del lenguaje hasta errores tipográficos. Por ejemplo, en lugar de

auto x = obj.x;
auto y = obj.y;
auto z = obj.z;

has escrito el siguiente código:

auto x = obj.x;
auto y = obj.y;
auto z = obj.x;

Como puedes ver, hay un error tipográfico en la última línea. Por ejemplo, PVS-Studio emite la siguiente advertencia:

V537 Considera revisar la corrección del uso del ítem 'y'.

Si deseas probar este error manualmente, prueba el ejemplo preparado en Compiler Explorer: *clic*.

Y como bien entiendes, no siempre se puede prestar atención a estos segmentos de código de inmediato, y esto puede hacer que te quedes atascado en la depuración por mucho tiempo, sin comprender por qué todo funciona de manera tan extraña.

Sin embargo, este es un error evidente. ¿Y si el desarrollador escribió un código subóptimo porque olvidó algún detalle del lenguaje? O incluso cometió un comportamiento indefinido en el código.? К сожалению, подобные случаи совершенно обыденны и львиная часть времени тратится на то, чтобы отладить специфично работающий код, который содержит опечатки, типичные ошибки или undefined behavior.

Fue precisamente para estas situaciones que nació el análisis estático. Es una herramienta para los desarrolladores que les indicará diversos problemas en el código y explicará en la documentación por qué no se debe escribir de esa manera, a qué puede conducir y cómo solucionarlo. Aquí hay un ejemplo de cómo puede lucir: *clic*.

Más errores interesantes que el analizador puede descubrir se pueden encontrar en los artículos:

Ahora, después de leer este material y de convencerse de la utilidad del análisis estático, puede que desee probarlo en acción. Pero, ¿por dónde empezar? ¿Cómo integrar una nueva herramienta en el proyecto actual? ¿Y cómo familiarizar al equipo con ella? Encontrará respuestas a estas preguntas a continuación.

Nota. El análisis estático no reemplaza ni anula una herramienta tan útil como las revisiones de código. Complementa este proceso, ayudando a notar y corregir errores tipográficos, imprecisiones y construcciones peligrosas de antemano. Es mucho más productivo concentrarse en los algoritmos y la claridad del código durante las revisiones de código, en lugar de buscar un paréntesis mal colocado o leer funciones de comparación aburridas.

0. Familiarización con la herramienta

Todo comienza con una versión de prueba. De hecho, es difícil decidir implementar algo en el proceso de desarrollo si nunca se ha visto la herramienta en acción. Por lo tanto, lo primero que debe hacer es descargar una versión de prueba.

Lo que aprenderá en esta etapa:

  • Cuáles son las formas de interactuar con el analizador;
  • Si el analizador es compatible con su entorno de desarrollo;
  • Qué problemas existen actualmente en sus proyectos.

Después de haber instalado todo lo necesario, lo primero que debe hacer es ejecutar un análisis de todo el proyecto (Windows, Linux, macOS). En el caso de PVS-Studio en Visual Studio, verá una imagen similar (clickeable):

Análisis estático – desde el conocimiento hasta la integración
El hecho es que, normalmente, los analizadores estáticos emiten una gran cantidad de advertencias en proyectos con una gran base de código. No es necesario corregirlas todas, ya que su proyecto ya está funcionando, lo que significa que estos problemas no son críticos. Sin embargo, usted puede echar un vistazo a las advertencias más interesantes y corregirlos si es necesario. Para ello, es necesario filtrar la salida y dejar solo los mensajes más fiables. En el plugin PVS-Studio para Visual Studio, esto se hace filtrando por niveles y categorías de errores. Para una salida más precisa, mantenga activadas solo Alto y General (también es clicable):

Análisis estático – desde el conocimiento hasta la integración
De hecho, revisar 178 advertencias es considerablemente más fácil que varias miles...

En las pestañas Medio y Bajo frecuentemente aparecen buenas advertencias, sin embargo, en estas categorías se incluyen diagnósticos que tienen menor precisión (fiabilidad). Puede ver más sobre los niveles de advertencias y las opciones de trabajo en Windows aquí: *clic*.

Después de revisar con éxito los errores más interesantes (y corregirlos exitosamente), deberías suprimir las advertencias restantes. Esto es necesario para que las nuevas advertencias no se pierdan entre las antiguas. Además, el analizador estático es una herramienta de ayuda para el programador, no una lista de errores. 🙂

1. Automatización

Después de familiarizarse, llega el momento de configurar los plugins e integrarse en CI. Esto es necesario hacerlo antes de que los programadores comiencen a usar el analizador estático. La cuestión es que el programador puede olvidar activar el análisis o, incluso, no querer hacerlo. Para ello, se necesita realizar una verificación final de todo, para que el código no verificado no pueda entrar en la rama principal de desarrollo.

Lo que aprenderás en esta etapa:

  • Qué opciones de automatización ofrece la herramienta;
  • Si el analizador es compatible con tu sistema de construcción.

Dado que no existe documentación perfecta, a veces es necesario escribir en soporte. Es normal, y estamos encantados de ayudarte. 🙂

Y ahora, pasemos a los servicios de integración continua (CI). Cualquier analizador se puede implementar en ellos sin problemas serios. Para ello, es necesario crear una etapa separada en el pipeline, que normalmente se encuentra después de la construcción y las pruebas unitarias. Esto se hace mediante varias utilidades de consola. Por ejemplo, PVS-Studio proporciona las siguientes utilidades:

Para integrar el análisis en CI, hay que hacer tres cosas:

  • Instalar el analizador;
  • Ejecutar el análisis;
  • Entregar resultados.

Por ejemplo, para instalar PVS-Studio en Linux (basado en Debian) se deben ejecutar los siguientes comandos:

wget -q -O - https://files.viva64.com/etc/pubkey.txt 
    | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list 
  https://files.viva64.com/etc/viva64.list
  
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio

En sistemas operativos Windows no es posible instalar el analizador desde el gestor de paquetes, sin embargo, se puede implementar el analizador desde la línea de comandos:

PVS-Studio_setup.exe /verysilent /suppressmsgboxes 
/norestart /nocloseapplications

Puede leer más sobre la implementación de PVS-Studio en sistemas operativos Windows *aquí*.

Después de la instalación, es necesario iniciar el análisis. Sin embargo, se recomienda hacerlo solo después de que se haya completado la compilación y las pruebas. Esto se debe a que el análisis estático generalmente requiere el doble de tiempo que la compilación.

Dado que la forma de iniciar depende de la plataforma y de las características del proyecto, mostraré un ejemplo para C++ (Linux):

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w

El primer comando realizará el análisis, y el segundo convertiráel informe a formato de texto, lo mostrará en pantalla y devolverá un código diferente de 0 en caso de advertencias. Este mecanismo es conveniente para bloquear la construcción si hay mensajes de error. Sin embargo, siempre puede eliminar la bandera -w y no bloquear la construcción que contiene advertencias.

Nota. El formato de texto es incómodo. Se proporciona solo como ejemplo. Preste atención a un formato de informe más interesante: FullHtml. Permite navegar por el código.

Puede leer más sobre la configuración del análisis en CI en el artículo "PVS-Studio y Continuous Integration" (Windows) o "Cómo configurar PVS-Studio en Travis CI" (Linux).

Está bien, ha configurado el analizador en el servidor de compilación. Ahora, si alguien sube código no verificado, fallará la etapa de verificación y podrá detectar el problema. Sin embargo, esto no es del todo conveniente, ya que es más efectivo verificar el proyecto antes de que ocurra la fusión de ramas, en la etapa de pull request.

En general, la configuración del análisis de pull request no difiere mucho de la ejecución normal del análisis en CI. A excepción de la necesidad de obtener la lista de archivos modificados. Por lo general, se pueden obtener solicitando la diferencia entre ramas usando git:

git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

Ahora es necesario pasar esta lista de archivos al analizador. Por ejemplo, en PVS-Studio esto se implementa mediante un flag. -S:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log 
                            -S .pvs-pr.list

Puedes obtener más información sobre el análisis de pull requests *aquí*. Incluso si tu CI no está en la lista de servicios mencionados en el artículo, te será útil la sección general dedicada a la teoría de este tipo de análisis.

Al configurar el análisis de pull requests, podrás bloquear commits que contengan advertencias, creando así un límite que el código no verificado no podrá cruzar.

Todo esto es, sin duda, bueno, pero me gustaría tener la posibilidad de ver todas las advertencias en un solo lugar. No solo del analizador estático, sino también de pruebas unitarias o de un analizador dinámico. Para eso existen varios servicios y plugins. PVS-Studio, por ejemplo, tiene un plugin para la integración en SonarQube..

2. Integración en las máquinas de los desarrolladores.

Ahora ha llegado el momento de instalar y configurar el analizador para su uso diario en el desarrollo. Hasta este punto ya te has familiarizado con la mayoría de los métodos de trabajo, por lo que esta puede considerarse la parte más fácil.

Como la opción más sencilla, los desarrolladores pueden instalar el analizador necesario por su cuenta. Sin embargo, esto tomará mucho tiempo y los desviará del desarrollo, por lo que puedes automatizar este proceso utilizando un instalador y los flags necesarios. Para PVS-Studio hay varios flags para la instalación automatizada.. Sin embargo, siempre hay gestores de paquetes, como Chocolatey (Windows), Homebrew (macOS) o decenas de opciones para Linux.

Luego será necesario instalar los plugins requeridos, por ejemplo, para Visual Studio., IDEA., Rider. etc.

3. Uso diario.

En esta etapa es hora de mencionar algunas formas de acelerar el trabajo del analizador en su uso diario. Un análisis completo de todo el proyecto toma mucho tiempo, pero ¿con qué frecuencia cambiamos el código en todo el proyecto de una vez? Es poco probable que exista una refactorización tan amplia que afecte de inmediato a toda la base de código. La cantidad de archivos modificados a la vez rara vez supera la docena, por lo que es sensato analizarlos. Para esta situación existe el modo de análisis incremental.. No se asusten, no es otra herramienta más. Es un modo especial que permite analizar solo los archivos modificados y sus dependencias, y esto ocurre automáticamente después de la compilación si trabajas en un IDE con el complemento instalado.

En caso de que el analizador detecte problemas en el código recientemente modificado, lo comunicará por sí mismo. Por ejemplo, PVS-Studio te lo hará saber mediante una notificación:

Análisis estático – desde el conocimiento hasta la integración
No es suficiente con decirles a los desarrolladores que usen la herramienta. Necesitamos de alguna manera contarles qué es y cómo funciona. Aquí, por ejemplo, hay artículos sobre cómo empezar rápidamente con PVS-Studio, aunque tutoriales similares los puedes encontrar para cualquier herramienta que prefieras:

Artículos como estos proporcionan toda la información necesaria para el uso cotidiano y no toman mucho tiempo. 🙂

Incluso en la etapa de familiarización con la herramienta, suprimimos muchas advertencias durante una de las primeras ejecuciones. Lamentablemente, los analizadores estáticos no son perfectos, por lo que de vez en cuando emiten falsas alarmas. Suprimirlas suele ser fácil, por ejemplo, en el complemento PVS-Studio para Visual Studio, solo debes presionar un botón:

Análisis estático – desde el conocimiento hasta la integración
Sin embargo, no solo puedes suprimirlas. Por ejemplo, puedes informar al soporte sobre la existencia de un problema. Si es posible corregir la falsa alarma, en futuras actualizaciones puedes notar que cada vez hay menos y menos falsas alarmas específicas de tu base de código.

Después de la integración

Hemos completado todas las etapas de la integración del análisis estático en el proceso de desarrollo. A pesar de la importancia de configurar tales herramientas en CI, el lugar más importante para la ejecución es precisamente la computadora del desarrollador. Porque el analizador estático no es un juez que te dice desde lejos que el código no sirve. Por el contrario, es un asistente que te ayuda si estás cansado y te recuerda si has olvidado algo.

La verdad es que, sin el uso regular, el análisis estático difícilmente simplificará significativamente el desarrollo. La principal utilidad para el desarrollador radica no tanto en encontrar secciones de código complejas y discutibles, sino en detectarlas temprano. Acepta que descubrir un problema cuando los cambios ya están en prueba no solo es desagradable, sino también muy prolongado. Sin embargo, el análisis estático, cuando se utiliza de manera regular, revisa cada cambio directamente en tu computadora y te informa sobre lugares sospechosos mientras trabajas en el código.

Y si tú o tus colegas todavía no están seguros sobre la implementación de un analizador, te sugiero que ahora leas el artículo "Razones para implementar un analizador estático de código PVS-Studio en el proceso de desarrollo". En él se abordan las preocupaciones típicas de los desarrolladores sobre cómo el análisis estático les robará tiempo, y así sucesivamente.

Análisis estático – desde el conocimiento hasta la integración

Si desea compartir este artículo con una audiencia de habla inglesa, le pido que utilice el enlace a la traducción: Maxim Zvyagintsev. Análisis Estático: Desde el Comienzo hasta la Integración.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster