Statische Analyse – von der Einführung bis zur Integration

Die Qual jeden endlosen Code-Reviews oder Debuggings bringt einen manchmal dazu, darüber nachzudenken, wie man sich das Leben einfacher machen könnte. Und beim Suchen oder zufällig Stoßen auf einen Begriff kann man die magische Wendung sehen: "Statische Analyse". Lassen Sie uns ansehen, was das ist und wie es mit Ihrem Projekt interagieren kann.

Statische Analyse – von der Einführung bis zur Integration
Eigentlich, wenn Sie in einer modernen Programmiersprache schreiben, dann haben Sie das unbewusst bereits durch einen statischen Analysator geleitet. Tatsache ist, dass jeder moderne Compiler zwar nur einen kleinen, aber feinen Satz an Warnungen über potenzielle Probleme im Code bereitstellt. Wenn Sie zum Beispiel C++-Code in Visual Studio kompilieren, sehen Sie Folgendes:

Statische Analyse – von der Einführung bis zur Integration
In dieser Ausgabe sehen wir, dass die Variable var nirgendwo in der Funktion verwendet wurde. Tatsächlich haben Sie also fast immer einen einfachen statischen Code-Analysator verwendet. Im Gegensatz zu professionellen Analysatoren wie Coverity, Klocwork oder PVS-Studio können jedoch die vom Compiler bereitgestellten Warnungen nur auf einen kleinen Bereich von Problemen hinweisen.

Wenn Sie sich nicht sicher sind, was statische Analyse ist und wie man sie implementiert, diesen Artikel, um mehr über diese Methodik zu erfahren.

Warum ist statische Analyse notwendig?

Kurz gesagt: Beschleunigung und Vereinfachung.

Statische Analyse ermöglicht es, eine Vielzahl von Problemen im Code zu finden: von falscher Verwendung der Sprachkonstrukte bis hin zu Tippfehlern. Zum Beispiel, anstelle von

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

haben Sie den folgenden Code geschrieben:

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

Wie Sie sehen, gibt es in der letzten Zeile einen Tippfehler. Zum Beispiel gibt PVS-Studio die folgende Warnung aus:

V537 Überprüfen Sie die Richtigkeit der Verwendung des ‘y’-Elements.

Wenn Sie diesen Fehler manuell überprüfen möchten, versuchen Sie ein Beispiel auf Compiler Explorer: *Klick*.

Und wie Sie verstehen, kann man nicht immer sofort auf solche Codestellen achten und dadurch kann man beim Debuggen eine Weile festhängen, ohne zu verstehen, warum alles so seltsam funktioniert.

Das ist jedoch ein offensichtlicher Fehler. Und was ist, wenn der Entwickler schlechten Code geschrieben hat, weil er eine Nuance der Sprache vergessen hat? Oder vielleicht hat er sogar im Code undefined behavior? К сожалению, подобные случаи совершенно обыденны и львиная часть времени тратится на то, чтобы отладить специфично работающий код, который содержит опечатки, типичные ошибки или undefined behavior.

Gerade für solche Situationen wurde die statische Analyse entwickelt. Sie ist ein Hilfsmittel für Entwickler, das auf verschiedene Probleme im Code hinweist und in der Dokumentation erklärt, warum man so nicht schreiben sollte, welche Folgen das haben kann und wie man es beheben kann. Hier ist ein Beispiel, wie das aussehen könnte: *Klick*.

Weitere interessante Fehler, die der Analyzer aufdecken kann, finden Sie in den Artikeln:

Nachdem Sie dieses Material gelesen und den Nutzen der statischen Analyse erkannt haben, möchten Sie sie vielleicht in der Praxis ausprobieren. Aber wo fängt man an? Wie integriert man ein neues Tool in ein bestehendes Projekt? Und wie stellt man das Team darauf ein? Antworten auf diese Fragen finden Sie weiter unten.

Hinweis. Statische Analyse ersetzt nicht und annulliert nicht so etwas Nützliches wie Code-Reviews. Sie ergänzt diesen Prozess, indem sie hilft, Tippfehler, Ungenauigkeiten und gefährliche Konstruktionen im Voraus zu erkennen und zu beheben. Es ist viel produktiver, sich bei Code-Reviews auf Algorithmen und die Verständlichkeit des Codes zu konzentrieren, anstatt nach falsch gesetzten Klammern oder langweiligen Vergleichsfunktionen zu suchen..

0. Einführung in das Tool

Alles beginnt mit einer Testversion. Es ist wirklich schwierig, irgendetwas in den Entwicklungsprozess einzuführen, wenn man das Tool noch nie live gesehen hat. Daher ist es ratsam, zuerst die Testversion herunterzuladen..

Was Sie in dieser Phase erfahren werden:

  • Welche Möglichkeiten der Interaktion mit dem Analyzer bestehen;
  • Ob der Analyzer mit Ihrer Entwicklungsumgebung kompatibel ist;
  • Welche Probleme derzeit in Ihren Projekten bestehen.

Nachdem Sie alles Notwendige installiert haben, sollten Sie als Erstes eine Analyse des gesamten Projekts durchführen (Windows, Linux, macOS). Im Fall von PVS-Studio in Visual Studio sehen Sie ein ähnliches Bild (klickbar):

Statische Analyse – von der Einführung bis zur Integration
Das Problem ist, dass statische Analyzer in der Regel eine enorme Menge an Warnungen für Projekte mit großen Codebasen ausgeben. Es ist nicht notwendig, sie alle zu beheben, da Ihr Projekt bereits funktioniert und diese Probleme daher nicht kritisch sind. Sie können jedoch die interessantesten Warnungen ansehen. und sie bei Bedarf zu korrigieren. Dazu muss die Ausgabe gefiltert werden, um nur die zuverlässigsten Meldungen zu belassen. Im PVS-Studio-Plugin für Visual Studio erfolgt dies durch Filterung nach Schweregraden und Fehlerkategorien. Für die genaueste Ausgabe lassen Sie nur die eingeschaltet, die Hoch und Allgemein (auch klickbar):

Statische Analyse – von der Einführung bis zur Integration
Tatsächlich ist es viel einfacher, 178 Warnungen zu überprüfen als mehrere Tausend…

In den Tabs Mittel und Niedrig kommen oft nützliche Warnungen vor, jedoch enthalten diese Kategorien Diagnosen, die eine geringere Genauigkeit (Zuverlässigkeit) aufweisen. Weitere Informationen zu den Warnstufen und den Arbeitsmöglichkeiten unter Windows finden Sie hier: *Klick*.

Nachdem Sie die interessantesten Fehler erfolgreich überprüft (und behoben) haben, sollten Sie die verbleibenden Warnungen unterdrücken. Dies ist notwendig, damit neue Warnungen nicht unter den alten verloren gehen. Außerdem ist der statische Analysator ein Helfer für den Programmierer und keine Fehlerliste. 🙂

1. Automatisierung

Nach der Einführung folgt die Zeit der Plugin-Einstellungen und der Integration in CI. Das muss erfolgen, bevor die Programmierer den statischen Analysator zu verwenden beginnen. Der Grund ist, dass der Programmierer vergessen kann, die Analyse zu aktivieren oder sie möglicherweise ganz ablehnt. Daher ist eine abschließende Überprüfung aller Dinge notwendig, damit ungeprüfter Code nicht in den Hauptentwicklungszweig gelangt.

Was Sie in diesem Schritt lernen werden:

  • Welche Automatisierungsoptionen das Tool bietet;
  • Ob der Analysator mit Ihrem Build-System kompatibel ist.

Da es keine perfekte Dokumentation gibt, muss man manchmal in Unterstützungschreiben. Das ist normal, und wir helfen Ihnen gerne. 🙂

Jetzt kommen wir zu den Continuous Integration (CI)-Diensten. Jeder Analysator kann ohne größere Probleme integriert werden. Dazu muss ein eigener Schritt im Pipeline erstellt werden, der normalerweise nach dem Build und den Unit-Tests erfolgt. Dies geschieht mithilfe verschiedener Konsolenutilities. Zum Beispiel stellt PVS-Studio die folgenden Tools zur Verfügung:

Für die Integration der Analyse in CI sind drei Dinge zu tun:

  • Den Analysator installieren;
  • Analyse starten;
  • Ergebnisse liefern.

Um PVS-Studio unter Linux (Debian-basiert) zu installieren, müssen Sie die folgenden Befehle ausführen:

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

In Windows-Systemen gibt es keine Möglichkeit, den Analysator über den Paketmanager zu installieren, jedoch kann der Analysator über die Befehlszeile installiert werden:

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

Weitere Informationen zur Bereitstellung von PVS-Studio auf Windows-Systemen finden Sie in *hier*.

Nach der Installation muss die eigentliche Analyse gestartet werden. Es wird jedoch empfohlen, dies nur durchzuführen, nachdem die Kompilierung und die Tests abgeschlossen sind. Dies liegt daran, dass die statische Analyse in der Regel doppelt so viel Zeit wie die Kompilierung benötigt.

Da die Art des Starts von der Plattform und den Besonderheiten des Projekts abhängt, zeige ich ein Beispiel für C++ (Linux):

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

Der erste Befehl führt die Analyse durch, und der zweite konvertiertden Bericht in ein Textformat, gibt ihn auf dem Bildschirm aus und gibt einen Rückgabewert ungleich 0 zurück, falls Warnungen vorliegen. Ein solches Verfahren ist nützlich, um den Build bei Fehlernachrichten zu blockieren. Sie können jedoch jederzeit das Flag entfernen -w und den Build nicht blockieren, der Warnungen enthält.

Hinweis. Das Textformat ist unpraktisch. Es wird nur als Beispiel angegeben. Beachten Sie das interessantere Berichtformat – FullHtml. Es ermöglicht die Navigation im Code.

Weitere Informationen zur Konfiguration der Analyse in CI finden Sie in dem Artikel "PVS-Studio und Continuous Integration" (Windows) oder "Wie man PVS-Studio in Travis CI einrichtet" (Linux).

Gut, Sie haben die Funktion des Analysators auf dem Build-Server eingerichtet. Wenn jemand unverifizierten Code hochgeladen hat, wird der Überprüfungsschritt fehlschlagen, und Sie können das Problem entdecken. Das ist jedoch nicht ganz praktisch, da es effektiver ist, das Projekt nicht nach dem Zusammenführen von Branches zu prüfen, sondern vorher, in der Phase des Pull-Requests.

Insgesamt unterscheidet sich die Konfiguration der Analyse des Pull-Requests nicht stark von einem normalen Analyse-Start in CI, außer dass die Liste der geänderten Dateien abgerufen werden muss. Diese können normalerweise durch Anfordern der Differenz zwischen den Branches mit git erhalten werden:

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

Jetzt muss diese Liste von Dateien dem Analyzer übergeben werden. Zum Beispiel wird dies in PVS-Studio mit der Option -S:

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

Mehr über die Analyse von Pull Requests kann man *hier*. erfahren. Selbst wenn Ihr CI nicht in der Liste der in dem Artikel genannten Dienste enthalten ist, wird Ihnen der allgemeine Abschnitt, der sich mit der Theorie dieser Art der Analyse befasst, nützlich sein.

Durch die Einrichtung der Pull Request-Analyse können Sie Commits blockieren, die Warnungen enthalten, und damit eine Grenze schaffen, die unüberprüften Code nicht überschreiten kann.

Das ist alles zweifellos gut, aber es wäre wünschenswert, alle Warnungen an einem Ort sehen zu können. Nicht nur von dem statischen Analyzer, sondern auch von Unit-Tests oder vom dynamischen Analyzer. Für dies gibt es verschiedene Dienste und Plugins. PVS-Studio hat zum Beispiel ein Plugin zur Integration in SonarQube.

2. Integration auf den Maschinen der Entwickler

Jetzt ist es Zeit, den Analyzer für den täglichen Gebrauch bei der Entwicklung zu installieren und zu konfigurieren. Zu diesem Zeitpunkt haben Sie bereits die meisten Arbeitsmethoden kennengelernt, daher kann dieser Teil als der einfachste bezeichnet werden.

Als einfachste Variante können die Entwickler den notwendigen Analyzer selbst installieren. Dies wird jedoch viel Zeit in Anspruch nehmen und sie von der Entwicklung ablenken, weshalb Sie diesen Prozess automatisieren können, indem Sie den Installer und die benötigten Flags verwenden. Für PVS-Studio gibt es verschiedene Flags für die automatisierte Installation. Es gibt jedoch immer Paketmanager wie Chocolatey (Windows), Homebrew (macOS) oder Dutzende von Optionen für Linux.

Dann müssen die notwendigen Plugins installiert werden, zum Beispiel für Visual Studio, IDEA, Rider usw.

3. Täglicher Gebrauch

An diesem Punkt ist es an der Zeit, ein paar Worte über Möglichkeiten zur Beschleunigung der Arbeit des Analyzers beim täglichen Gebrauch zu verlieren. Eine vollständige Analyse des gesamten Projekts dauert sehr lange, aber wie oft ändern wir den Code auf einmal in dem gesamten Projekt? Es gibt kaum einen so umfassenden Refactoring-Vorgang, der den gesamten Code betreffen würde. Die Anzahl der gleichzeitig geänderten Dateien übersteigt selten ein Dutzend, weshalb es sinnvoll ist, diese zu analysieren. Für eine solche Situation gibt es den Inkremental-Analysemodus. Bitte keine Angst, das ist kein weiteres Tool. Dies ist ein spezieller Modus, der es ermöglicht, nur geänderte Dateien und deren Abhängigkeiten automatisch nach dem Bau zu analysieren, wenn Sie in einer IDE mit installiertem Plugin arbeiten.

Falls der Analysator Probleme im kürzlich geänderten Code findet, wird er Sie darüber informieren. Zum Beispiel wird PVS-Studio Ihnen darüber mit einer Benachrichtigung Bescheid geben:

Statische Analyse – von der Einführung bis zur Integration
Es reicht jedoch nicht aus, den Entwicklern zu sagen, sie sollen das Tool verwenden. Man muss ihnen irgendwie erklären, was das überhaupt ist und wie es funktioniert. Hier sind beispielsweise Artikel für den schnellen Einstieg in PVS-Studio, ähnliche Tutorials finden Sie jedoch für jedes bevorzugte Tool:

Solche Artikel bieten alle notwendigen Informationen für den täglichen Gebrauch und nehmen nicht viel Zeit in Anspruch. 🙂

Schon beim Kennenlernen des Tools haben wir eine Menge Warnungen während eines der ersten Starts unterdrückt. Leider sind statische Analysatoren nicht perfekt, weshalb sie gelegentlich falsche Alarme auslösen. Diese zu unterdrücken ist in der Regel einfach, im PVS-Studio Plugin für Visual Studio genügt ein Klick auf einen Button:

Statische Analyse – von der Einführung bis zur Integration
Sie können sie jedoch nicht nur unterdrücken. Beispielsweise können Sie den Support über das Vorhandensein eines Problems informieren. Wenn ein falscher Alarm behoben werden kann, können Sie in zukünftigen Updates feststellen, dass die Anzahl der spezifischen Fehlalarme für Ihre Codebasis immer weiter abnimmt.

Nach der Integration

Jetzt haben wir alle Phasen zur Integration der statischen Analyse in den Entwicklungsprozess durchlaufen. Trotz der Bedeutung der Konfiguration solcher Tools im CI ist der wichtigste Ort des Starts der Computer des Entwicklers. Denn der statische Analysator ist kein Richter, der irgendwo weit von Ihnen entfernt sagt, dass der Code nicht taugt. Vielmehr ist er ein Helfer, der Sie unterstützt, wenn Sie müde sind, und Sie daran erinnert, wenn Sie etwas vergessen haben.

Die Wahrheit ist, dass die regelmäßige Nutzung von statischer Analyse die Entwicklung wahrscheinlich nicht signifikant erleichtert. Denn der größte Nutzen für den Entwickler liegt weniger im Auffinden komplexer und umstrittener Codestellen, sondern vielmehr in ihrer frühzeitigen Entdeckung. Sie werden zustimmen, dass es unangenehm und zeitaufwändig ist, ein Problem zu erkennen, wenn die Änderungen bereits in der Testphase sind. Die statische Analyse hingegen überprüft bei regelmäßiger Nutzung jede Änderung direkt auf Ihrem Computer und meldet verdächtige Stellen während der Arbeit am Code.

Und wenn Sie oder Ihre Kollegen immer noch unsicher sind, ob Sie einen Analysator einführen sollen, dann schlage ich vor, jetzt den Artikel "Gründe für die Einführung eines statischen Code-Analysewerkzeugs PVS-Studio in den Entwicklungsprozess" zu lesen. Darin werden typische Bedenken der Entwickler behandelt, dass statische Analyse ihre Zeit in Anspruch nehmen wird und so weiter.

Statische Analyse – von der Einführung bis zur Integration

Wenn Sie diesen Artikel mit einem englischsprachigen Publikum teilen möchten, verwenden Sie bitte den Link zur Übersetzung: Maxim Zvyagintsev. Statische Analyse: Von den ersten Schritten bis zur Integration.

Quelle: habr.com

60GB SSD 8Gb DDR4