PVS Studio.VS. Statistische Analyse von GCC 10. Unabhängiger Minitest

Nach dem Erscheinen des übersetzten Artikels über statische Analyse in GCC 10 und der erwarteten Reaktion der Vertreter des Entwicklers des kommerziellen statischen Analysators PVS-Studio, die hier sind, fragte ich: „Warum weigern sich die Vertreter , ihr Produkt mit so einfachen Beispielen für statische Analyse zu testen , und verstecken sie sich was sind Sie? "
Andrey2008Ja, das interessiert mich nicht. Gefangen / hat keinen synthetischen Fehler festgestellt, dies sagt nichts über die Fähigkeiten des Analysators aus
Sollten sie irgendwie die Unit-Tests ihres Produkts durchführen und wie, wenn nicht mit solchen synthetischen einfachen Beispielen ?!

Eigentlich musste ich es selbst machen.

Test Nummer 1. Das einfachste Beispiel für einen doppelten freien Fehler


Diagnose mit:
V586 Die Funktion 'frei' wird zweimal aufgerufen, um den gleichen Speicherplatz freizugeben. Überprüfen Sie das erste Argument. Überprüfen Sie die Zeilen: 5, 6. 1_dbl_free.c 6

Bestanden

Test Nummer 2. longjmp () von free ()


Unverständliches Schwören auf eine Konstante in Malloc, aber es wurde ein Fehler festgestellt - unzugänglicher Code und nicht verwendeter Speicher:
Die Funktion V118 malloc () akzeptiert einen gefährlichen Ausdruck in der Eigenschaft eines Arguments. 2_longjump.c 13
V779 Nicht erreichbarer Code erkannt. Möglicherweise liegt ein Fehler vor. 2_longjump.c 15
V799 Die Variable 'ptr' wird nicht verwendet, nachdem Speicher dafür zugewiesen wurde. Überprüfen Sie die Verwendung dieser Variablen. 2_longjump.c 13

Bestanden

Test Nummer 3. Malloc () leckt und fopen () nicht geschlossene Dateien


Gefunden:
Die Funktion V118 malloc () akzeptiert einen gefährlichen Ausdruck in der Eigenschaft eines Arguments. 3_fopen.c 7
V773 Der Sichtbarkeitsbereich des ' f'- Dateihandles wurde beendet, ohne die Datei zu schließen. Ein Ressourcenleck ist möglich. 3_fopen.c 9
V773 Der Sichtbarkeitsbereich des 'p'-Zeigers wurde beendet, ohne den Speicher freizugeben. Ein Speicherverlust ist möglich. 3_fopen.c 9
V799 Die Variable 'p' wird nicht verwendet, nachdem Speicher dafür zugewiesen wurde. Überprüfen Sie die Verwendung dieser Variablen. 3_fopen.c 7

Bestanden

Test Nummer 4. Überwachen der Speichernutzung nach dem Freigeben



Fehler erkannt : V774 Der Zeiger 'n' wurde verwendet, nachdem der Speicher freigegeben wurde. 4_use_after_free.c 9
V591 Die nicht leere Funktion sollte einen Wert zurückgeben. 4_use_after_free.c 11

Bestanden

Test Nummer 5. Steuerung der Freigabe von Zeigern ohne Heap (Heap)


Es wurden fehlerfreie Warnungen ausgegeben:
V104 Implizite Konvertierung von 'n' in memsize-Typ in einem arithmetischen Ausdruck: sizeof (int) * n 5_free_nonheap.c 11
V799 Die Variable 'ptr' wird nicht verwendet, nachdem Speicher dafür zugewiesen wurde. Überprüfen Sie die Verwendung dieser Variablen. 5_free_nonheap.c 11

Fehlgeschlagen

Test Nummer 6. Ungültiger Aufruf im Signal () -Handler


Fehlgeschlagen

Obwohl dies eine so spezifische Diagnose ist, dass ich sie nicht vorwerfen würde.

Als nächstes ging ich die Liste der Diagnosen in GCC 10 durch und fügte Beispiele hinzu, also weitere Tests mit Quellcodes.

Test Nummer 7. Doppeltes Schließen einer Datei und Freigeben einer geschlossenen DATEI *


PVS hat diese Fehler nicht
erkannt. GCC 10 hat Double-Fclose erkannt, aber für einen geschlossenen Griff nicht frei erkannt.

#include <stdlib.h>
void closefile(FILE* f) {
	fclose(f);
}

void test(const char *filename) {
  FILE *f = fopen(filename, "r");
  void *p = malloc(1024);
  /* do stuff */
  closefile(f);
  fclose(f);
  free (p);
  free(f);  // <-  UB
}

Gescheitert

Test Nummer 8. longjmp () auf einem veralteten Stapel


PVS bemerkte nichts, GCC10 funktionierte korrekt

#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();
}

Gescheitert

Test Nummer 9. Zeiger auf Stapelvariable zurückgeben


Von beiden Teilnehmern fehlgeschlagen, obwohl GCC dies in einfachen Fällen erkennt, dies jedoch nicht die -fanalyzer- Funktion ist (oder möglicherweise noch nicht implementiert ist).

#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;
}

Gescheitert

Test Nummer 10. Tainted-Array-Index und Verwendung von nicht initialisierten Wertediagnosen


Es sieht so aus, als ob sie noch nicht im GCC10- Analysator arbeiten .

PVS fängt dies auf, wie schon oft gezeigt wurde.

Bestanden

Fazit


In PVS-Studio gibt es definitiv eine statische Analyse.

Obwohl nicht ohne Nachteile, lohnt es sich, es zu verwenden, zumal viele menschliche Fehler nicht nur im Bereich der statischen Analyse erkannt werden.

All Articles