Um die Qualität der Software zu überprüfen, müssen Sie viele verschiedene Tools verwenden, einschließlich statischer und dynamischer Analysegeräte. In diesem Artikel versuchen wir herauszufinden, warum nur eine Art von Analyse, ob statisch oder dynamisch, für eine umfassende Softwareanalyse möglicherweise nicht ausreicht und warum es vorzuziehen ist, beide zu verwenden.

Unser Team schreibt viel über die Nützlichkeit der statischen Analyse und die Vorteile, die sie für Ihre Projekte mit sich bringt. Wir möchten unser Tool in verschiedenen Open-Source-Projekten ausführen, um mögliche Fehler zu finden. Auf diese Weise können wir die statische Code-Analysemethode bekannt machen. Die statische Analyse trägt wiederum dazu bei, Programme qualitativ hochwertiger und zuverlässiger zu machen und die Anzahl potenzieller Schwachstellen zu verringern. Vielleicht hat jeder, der direkt an der Arbeit am Quellcode beteiligt ist, das Gefühl der Zufriedenheit, Fehler behoben zu haben. Aber selbst wenn das erfolgreiche Erkennen (und Beheben) von Fehlern Ihre Endorphine nicht auslöst, genießen Sie sicherlich den Gedanken, die Entwicklungskosten dank des statischen Analysators zu senken, der Ihren Programmierern geholfen hat, ihre Zeit effektiver und effizienter zu nutzen. In
diesem Artikel erfahren Sie mehr darüber, wie Sie von der Verwendung statischer Analysen in Bezug auf Geld profitieren können. Es gibt eine ungefähre Schätzung für PVS-Studio, aber diese Ergebnisse können auf andere auf dem Markt verfügbare statische Analysewerkzeuge hochgerechnet werden.
Alles oben Gesagte scheint darauf hinzudeuten, dass der Zweck der statischen Analyse darin besteht, Fehler im Quellcode so früh wie möglich zu finden, wodurch die Kosten für die Fehlerbehebung reduziert werden. Aber warum brauchen wir dann eine dynamische Analyse und warum kann es unzureichend sein, sich nur an eine der beiden Techniken zu halten? Lassen Sie uns formellere und klarere Definitionen statischer und dynamischer Analysen geben und versuchen, diese Fragen zu beantworten.
Bei der statischen Code-Analyse werden Fehler und Code-Gerüche im Quellcode der Software erkannt. Um ein Programm zu analysieren, müssen Sie es nicht ausführen. Die Analyse wird auf der verfügbaren Codebasis durchgeführt. Die der statischen Analyse am nächsten kommende Analogie ist die sogenannte Codeüberprüfung, mit der Ausnahme, dass die statische Analyse eine automatisierte Version der Codeüberprüfung ist (dh von einem Bot-Programm durchgeführt wird).
Die Hauptvorteile der statischen Analyse:
- Fehlererkennung in der frühen Entwicklungsphase. Dies trägt dazu bei, die Fehlerbehebung viel billiger zu machen, da die Fehlerbehebung umso einfacher und damit umso billiger ist, je früher ein Fehler erkannt wird.
- Damit können Sie den potenziellen Fehler im Quellcode genau lokalisieren.
- Volle Codeabdeckung. Unabhängig davon, wie oft der eine oder andere Codeblock während der Ausführung die Kontrolle erhält, überprüft die statische Analyse die gesamte Codebasis.
- Einfach zu bedienen. Sie müssen keine Eingabedatensätze vorbereiten, um eine Überprüfung durchzuführen.
- Statische Analysegeräte erkennen Tippfehler und Fehler beim Kopieren und Einfügen relativ schnell und einfach.
Die objektiven Nachteile der statischen Analyse:
- Unvermeidliche Fehlalarme. Ein statischer Analysator kann sich über Codefragmente ärgern, die tatsächlich keine Fehler enthalten. Nur der Programmierer kann dieses Problem lösen und eine Warnung als falsch positiv markieren, was bedeutet, dass dies einen Teil seiner Arbeitszeit in Anspruch nimmt.
- Die statische Analyse ist im Allgemeinen schlecht darin, Speicherlecks und Fehler im Zusammenhang mit der Parallelität zu erkennen. Um solche Fehler zu erkennen, müssten Sie tatsächlich einen Teil des Programms im virtuellen Modus ausführen, was eine äußerst schwierige Aufgabe ist. Außerdem würden solche Algorithmen zu viel Speicher und CPU-Zeit erfordern. Statische Analysegeräte gehen normalerweise nicht weiter als die Analyse einiger einfacher Fälle . Dynamische Analysegeräte eignen sich besser zur Diagnose von Speicherlecks und Fehlern im Zusammenhang mit der Parallelität.
Es ist zu beachten, dass sich statische Analysegeräte nicht ausschließlich auf das Auffinden von Fehlern konzentrieren. Sie können beispielsweise Empfehlungen zur Code-Formatierung geben. Mit einigen Tools können Sie Ihren Code auf Übereinstimmung mit dem Codierungsstandard überprüfen, an den sich Ihr Unternehmen hält. Dies umfasst das Einrücken verschiedener Konstrukte, die Verwendung von Leerzeichen / Tabellierungszeichen usw. Darüber hinaus kann die statische Analyse zur Messung von Metriken hilfreich sein. Eine Software-Metrik ist ein quantitatives Maß dafür, inwieweit ein Programm oder seine Spezifikationen eine Eigenschaft besitzen. In
diesem Artikel erfahren Sie mehr über andere Anwendungen der statischen Analyse.
Dynamische Codeanalyse ist die Analyse, die zur Ausführungszeit an einem Programm durchgeführt wird. Dies bedeutet, dass Sie Ihren Quellcode zuerst in eine ausführbare Datei konvertieren müssen. Mit anderen Worten, Code, der Kompilierungs- oder Erstellungsfehler enthält, kann durch diese Art der Analyse nicht überprüft werden. Die Überprüfung erfolgt mit einem Satz von Eingabedaten, die dem zu analysierenden Programm zugeführt werden. Deshalb hängt die Wirksamkeit der dynamischen Analyse direkt von der Qualität und Quantität der Testeingabedaten ab. Diese Daten bestimmen den Umfang der Codeabdeckung am Ende des Tests.
Mit dynamischen Tests können Sie die folgenden Metriken und Warnungen erhalten:
- Verwendete Ressourcen: Ausführungszeit des gesamten Programms oder seiner einzelnen Teile, Anzahl der externen Abfragen (z. B. an eine Datenbank), RAM-Größe und andere vom Programm verwendete Ressourcen.
- Der Umfang der Codeabdeckung durch Tests und andere Metriken.
- Softwarefehler: Division durch Null, Null-Dereferenzierung, Speicherlecks, Rennbedingungen.
- Einige Sicherheitslücken.
Die Hauptvorteile der dynamischen Analyse:
- Sie müssen keinen Zugriff auf den Quellcode des Programms haben, um ihn zu analysieren. Es ist jedoch zu beachten, dass dynamische Analysewerkzeuge sich durch die Art und Weise unterscheiden, in der sie mit dem zu analysierenden Programm interagieren (dies wird hier ausführlicher erläutert). Beispielsweise beinhaltet eine ziemlich übliche dynamische Analysetechnik die Code-Instrumentierung vor der Prüfung, d. H. Das Hinzufügen spezieller Codefragmente zum Quellcode der Anwendung, damit der Analysator Fehler diagnostizieren kann. In diesem Fall benötigen Sie den Quellcode des Programms.
- Es kann komplexe Speicherbehandlungsfehler erkennen, z. B. Indizierung über Arraygrenzen hinweg und Speicherlecks.
- Es kann Multithread-Code zur Ausführungszeit analysieren und so potenzielle Probleme erkennen, die mit dem Zugriff auf gemeinsam genutzte Ressourcen oder möglichen Deadlocks zu tun haben.
- Die meisten Implementierungen von dynamischen Analysatoren erzeugen keine Fehlalarme, da Fehler beim Auftreten abgefangen werden. Daher ist eine von einem dynamischen Analysator ausgegebene Warnung keine vom Tool auf der Grundlage der Analyse des Programmmodells erstellte Vorhersage, sondern lediglich eine Aussage darüber, dass ein Fehler aufgetreten ist.
Die Nachteile der dynamischen Analyse:
- Eine vollständige Codeabdeckung ist nicht garantiert. Das heißt, es ist sehr unwahrscheinlich, dass Sie durch dynamische Tests eine 100% ige Abdeckung erhalten.
- Dynamische Analysatoren können Logikfehler nur schlecht erkennen. Zum Beispiel ist eine immer wahre Bedingung aus Sicht eines dynamischen Analysators kein Fehler, da eine solche falsche Prüfung einfach früher beim Kompilierungsschritt verschwindet.
- Es ist schwieriger, den Fehler im Code genau zu lokalisieren.
- Die dynamische Analyse ist im Vergleich zur statischen Analyse schwieriger zu verwenden, da Sie dem Programm genügend Daten zuführen müssen, um bessere Ergebnisse zu erzielen und eine möglichst vollständige Codeabdeckung zu erzielen.
Die dynamische Analyse ist besonders nützlich in Bereichen, in denen Programmzuverlässigkeit, Reaktionszeit oder verbrauchte Ressourcen das Hauptanliegen sind. Ein Echtzeitsystem, das einen kritischen Produktionssektor verwaltet, oder ein Datenbankserver sind einige Beispiele für solche Systeme. Jeder Fehler in diesen Bereichen kann kritisch sein.
Um auf die Frage zurückzukommen, warum es möglicherweise nicht ausreicht, nur an einer der beiden Analysetypen festzuhalten, werfen wir einen Blick auf einige recht triviale Beispiele für Fehler, bei denen eine Analysemethode keine Probleme bei der Diagnose hat, während die andere nicht erkannt werden kann und umgekehrt.
Das folgende Beispiel stammt aus dem Clang-Projekt:
MapTy PerPtrTopDown; MapTy PerPtrBottomUp; void clearBottomUpPointers() { PerPtrTopDown.clear(); } void clearTopDownPointers() { PerPtrTopDown.clear(); }
Ein statischer Analysator würde darauf hinweisen, dass die Körper der beiden Funktionen identisch sind. Natürlich sind zwei Funktionen mit identischen Körpern nicht unbedingt ein eindeutiges Zeichen für einen Fehler, aber es ist sehr wahrscheinlich, dass sie auf die Verwendung der Copy-Paste-Technik in Kombination mit Nachlässigkeit auf der Seite des Programmierers zurückzuführen sind - und dies führt zu unerwartetem Verhalten. In diesem Fall sollte die Methode
clearBottomUpPointers die Methode
PerPtrBottomUp.clear aufrufen. Die dynamische Analyse würde in diesem Beispiel nichts Falsches bemerken, da es sich aus seiner Sicht um einen absolut legitimen Code handelt.
Ein weiteres Beispiel. Angenommen, wir haben die folgende Funktion:
void OutstandingIssue(const char *strCount) { unsigned nCount; sscanf_s(strCount, "%u", &nCount); int array[10]; memset(array, 0, nCount * sizeof(int)); }
Theoretisch könnte ein statischer Analysator vermuten, dass mit diesem Code etwas nicht stimmt, aber die Implementierung einer solchen Diagnose ist eine sehr schwierige und sinnlose Aufgabe. Das Beispiel stammt aus
diesem Artikel , in dem auch erläutert wird, warum es eine schlechte Idee ist, statischen Analysatoren beizubringen, wie solche Fehler diagnostiziert werden. Kurz
gesagt , statische Analysatoren können sehr schlecht herausfinden, dass ein Aufruf der
Memset- Funktion zu einer Indizierung über die Array-Grenzen hinaus führen kann, da sie nicht vorhersehen können, welche Nummer aus der
strCount- Zeichenfolge gelesen wird. und wenn der Wert von
strCount aus einer Datei gelesen wird, wird dies zu einer unmöglichen Aufgabe für die statische Analyse insgesamt. Andererseits würde ein dynamischer Analysator keine Probleme haben, den Speicherbehandlungsfehler in diesem Code zu bemerken und darauf hinzuweisen (vorausgesetzt, das Programm erhält die richtigen Daten).
Dieser Artikel zielt nicht darauf ab, statische und dynamische Analysen zu vergleichen. Es gibt keine einzige Technik, mit der die gesamte Vielfalt von Softwarefehlern diagnostiziert werden könnte. Keine der beiden Analysetypen kann die andere vollständig ersetzen. Um die Qualität Ihrer Programme zu verbessern, müssen Sie verschiedene Arten von Tools verwenden, damit sie sich ergänzen. Ich hoffe, die oben gezeigten Beispiele überzeugen genug.
Ich möchte nicht zu voreingenommen gegenüber statischen Analysen sein, aber es ist diese Technik, von der in letzter Zeit am meisten gesprochen wird und die vor allem von Unternehmen in ihre CI-Prozesse einbezogen wird. Die statische Analyse ist einer der Schritte der sogenannten Qualitätstore zum Aufbau eines zuverlässigen und qualitativ hochwertigen Softwareprodukts. Wir glauben, dass statische Analysen in ein paar Jahren zu einer Standardpraxis für die Softwareentwicklung werden werden, genau wie einst Unit-Tests.
Abschließend möchte ich noch einmal darauf hinweisen, dass dynamische Analyse und statische Analyse nur zwei verschiedene Methoden sind, die sich gegenseitig ergänzen. Letztendlich dienen alle diese Techniken dem einzigen Zweck, die Softwarequalität zu erhöhen und die Entwicklungskosten zu senken.
Referenzen:- Terminologie. Statische Code-Analyse .
- Terminologie. Dynamische Code-Analyse .
- Andrey Karpov. Statische und dynamische Code-Analyse .
- Andrey Karpov. Mythen über statische Analyse. Der dritte Mythos - dynamische Analyse ist besser als statische Analyse .
- Andrey Karpov. PVS-Studio ROI .