Después de la aparición del artículo traducido sobre Análisis estático en GCC 10 , y la reacción esperada de los representantes del desarrollador del analizador estático comercial PVS-Studio que están aquí, pregunté: "¿Por qué los representantes se niegan a probar su producto con ejemplos tan simples para el análisis estático, y no se esconden? ¿Qué son? "Andrey2008Sí, no me interesa. Capturó / no detectó un error sintético, esto no dice nada sobre las capacidades del analizador
¿Deberían de alguna manera ejecutar las pruebas unitarias de su producto y cómo, si no con ejemplos sintéticos tan simples?En realidad, tuve que hacerlo yo mismo.Prueba número 1. El ejemplo más simple de un error doble libre
Diagnosticado con:V586 La función 'libre' se llama dos veces para desasignar el mismo espacio de memoria. Inspecciona el primer argumento. Verifique las líneas: 5, 6. 1_dbl_free.c 6PasóPrueba número 2. longjmp () por free ()
Juramento incomprensible en una constante en malloc, pero se detectó un error: código inaccesible y memoria no utilizada: la funciónV118 malloc () acepta una expresión peligrosa en la capacidad de un argumento. 2_longjump.c 13V779 Código inalcanzable detectado. Es posible que haya un error presente. 2_longjump.c 15V799 La variable 'ptr' no se usa después de que se le haya asignado memoria. Considere verificar el uso de esta variable. 2_longjump.c 13AprobadoPrueba número 3. Malloc () fugas y fopen () archivos no cerrados
Encontrado: la funciónV118 malloc () acepta una expresión peligrosa en la capacidad de un argumento. 3_fopen.c 7V773 El alcance de visibilidad del identificador de archivo 'f' se cerró sin cerrar el archivo. Una fuga de recursos es posible. 3_fopen.c 9V773 El alcance de visibilidad del puntero 'p' se salió sin liberar la memoria. Una pérdida de memoria es posible. 3_fopen.c 9V799 La variable 'p' no se usa después de que se le haya asignado memoria. Considere verificar el uso de esta variable. 3_fopen.c 7AprobadoPrueba número 4. Monitorear el uso de memoria después de liberarlo
Error detectado:V774 El puntero 'n' se usó después de liberar la memoria. 4_use_after_free.c 9V591 La función no nula debería devolver un valor. 4_use_after_free.c 11AprobadoPrueba número 5. Control de liberación de puntero sin almacenamiento dinámico (almacenamiento dinámico)
Se emitieron advertencias sin error:V104 Conversión implícita de 'n' al tipo memsize en una expresión aritmética: sizeof (int) * n 5_free_nonheap.c 11V799 La variable 'ptr' no se usa después de que se le haya asignado memoria. Considere verificar el uso de esta variable. 5_free_nonheap.c 11FallóPrueba número 6. Llamada no válida controlador de señal interna ()
FallóAunque este es un diagnóstico tan específico que no lo reprocharía.Luego, revisé la lista de diagnósticos en GCC 10 y agregué ejemplos, por lo que realicé más pruebas con los códigos fuente.Prueba número 7. Doble cierre de un archivo y liberación de un archivo cerrado *
PVS no detectó estos errores.GCC 10 detectó doble cierre pero no detectó libre para un identificador cerrado.#include <stdlib.h>
void closefile(FILE* f) {
fclose(f);
}
void test(const char *filename) {
FILE *f = fopen(filename, "r");
void *p = malloc(1024);
closefile(f);
fclose(f);
free (p);
free(f);
}
Ha falladoPrueba número 8. longjmp () en una pila obsoleta
PVS no notó nada, GCC10 funcionó correctamente#include <setjmp.h>
#include <stdlib.h>
static jmp_buf env;
static int i;
static void inner(void) {
longjmp(env, 1);
}
static void middle(void) {
inner();
}
void outer(void) {
i = setjmp(env);
}
void outer_x2(void) {
outer();
if (i == 0)
middle();
}
Ha falladoPrueba número 9. Regresar el puntero a la variable de pila
Ambos participantes fallaron, aunque en casos simples, GCC lo detecta, pero esta no es la función -fanalyzer (o puede que aún no se implemente).#include<stdlib.h>
struct str1 {
char buf[10];
};
struct str1 * ret(int sel)
{
struct str1 var1, *pval;
if(sel == 1)
pval = &var1;
else if(sel != 1)
pval = (struct str1 *)malloc(1000);
return pval;
}
Ha falladoPrueba número 10. Tainted-array-index y diagnóstico de uso de valor no inicializado
Parece que todavía no funcionan en el fanalyzer GCC10 .PVS atrapa esto, como se ha demostrado muchas veces.PasadoConclusión
Definitivamente hay un análisis estático en PVS-Studio.Aunque no sin algunos inconvenientes, vale la pena usarlo, especialmente porque se detectarán muchos errores humanos, no solo desde el campo del análisis estático.