Suchen

Statische Softwareanalyse Wie sich Software ohne Testfälle testen lässt

| Autor / Redakteur: Frank Büchner * / Hendrik Härter

In unserem Beitrag zeigen wir, wie sich mit statischer Analyse ohne großen Aufwand Fehler finden lassen. Der Code wird nicht ausgeführt, sondern mit Model Checking überprüft.

Firmen zum Thema

Softwaretest: Goanna analysiert Programme in C und C++ und arbeitet mit Eclipse/CDT und Visual Studio zusammen.
Softwaretest: Goanna analysiert Programme in C und C++ und arbeitet mit Eclipse/CDT und Visual Studio zusammen.
(Bild: Hitex)

Der größte Aufwand beim klassischen, dynamischen Testen entsteht beim Erstellen von guten Testfällen. Bei der werkzeuggestützten statischen Analyse entfällt dieser Aufwand. Bei der statischen Analyse wird der Programmcode nicht ausgeführt, sondern beispielsweise rein syntaktisch auf die Verletzung von vorgegebenen Regeln geprüft und/oder mit modernen Methoden, wie beispielsweise Model Checking, untersucht.

Begonnen hat die statische Analyse mit Programmen, die beispielweise überprüfen, ob die Anzahl der Parameter beim Aufruf einer C-Funktion dieselbe ist wie bei der Definition der Funktion. Der klassische Vertreter ist das Program lint. Die dabei aufgedeckten Probleme lassen sich überwiegend als Fehler einstufen, die dafür sorgen, dass das Programm nicht fehlerfrei abläuft. Wenn eine Funktion mit weniger Parametern aufgerufen wird als diese Funktion erwartet, kann das nicht gut gehen.

Bildergalerie

Mittlerweile werden solche Probleme größtenteils von Compilern erkannt. Während die Compiler immer mehr Aufgaben der klassischen Prüfprogramme übernahmen, fielen diesen Programmen neue Aufgaben zu: Sie überprüfen Programmierregeln und Programmiervorgaben. Ursprünglich waren das meist firmenspezifische Standards, wie die Forderung nach einheitlicher Benennung von Variablen in Bezug auf Groß-/Kleinschreibung oder nach der Angabe des Datentyps im Variablennamen anhand der Umgekehrten Polnischen Notation oder nach einem vorgegebenen Anteil von Kommentaren am Programmtext.

Wie sich Metriken in der Software bestimmen lassen

Letzteres oder das Ermitteln von Komplexitätsmaßen für einen Programmtext fällt genaugenommen unter das Thema „Bestimmung von Metriken“. Hier werden statistische Kennzahlen für das Programm ermittelt und es wird geprüft, ob diese Kennzahlen den Vorgaben entsprechen oder nicht. Das ist natürlich ebenfalls statische Analyse. Werden allerdings Metriken bestimmt, deckt dies keine funktionalen Fehler des Programms auf, sondern Metriken bewerten Eigenschaften wie Wartbarkeit oder Komplexität des Programms.

Werden Codierregeln überprüft, so wird versucht, potentielle Fehler des Programms zu vermeiden. Dabei wird zusätzlich versucht, verdächtige Programmkonstrukte zu finden, bei denen der Programmierer wahrscheinlich nicht das Programmverhalten erzielen wollte, das er tatsächlich programmiert hat. Gegenwärtig existieren verschiedene Programmierregelsätze für unterschiedliche Sprachen wie beispielsweise für C, C++, Java, Perl mit unterschiedlichen Schwerpunkten.

Einfache Muster erkennen nach MISRA-C:2004 oder MISRA-C++:2008

Die Mutter aller Programmierstandards sind die von MIRA (UK) herausgegebenen „Guidelines for the use of the C language in critical systems“. Die erste Ausgabe der Regeln für die Programmiersprache C stammt aus dem Jahr 1998. Eine überarbeitete Fassung kam im Jahr 2004 heraus. Vier Jahre später wurde ein Regelwerk für die Programmiersprache C++ herausgegeben. Eine Gemeinsamkeit haben alle Programmierstandards in allen Programmierregelsätzen: Viele Regeln lassen sich durch eine einfache, oft lokale Analyse des Programmtexts prüfen.

Es reicht häufig eine einfache Mustererkennung oder „Pattern Matching“ aus. Es müssen manchmal etwas aufwändigere syntaktische Muster erkannt werden. Die Regel 7.1 der MISRA-C:2004 oder Regel 2-13-2 der MISRA-C++:2008 Guidelines ist ein Beispiel für die einfache Mustererkennung. Die Regel verbietet den Gebrauch von oktalen Konstanten und auch von oktalen Escape-Sequenzen. Eine oktale Konstante in der Programmiersprache C ist eine Zahl, die mit der Ziffer 0 beginnt. Die Null ist genaugenommen selbst eine oktale Konstante, diese ist aber explizit von der Regel ausgenommen. Die Regel soll Missverständnisse bei der Bedeutung des Programmcodes vermeiden.

Im Bild 1 sind „001“ und „010“ beides oktale Konstanten. Während „001“ tatsächlich den Wert eins darstellt, ergibt „010“ den Wert acht und nicht zehn, wie man auf den ersten Blick meinen könnte. Ein Werkzeug kann relativ einfach prüfen, ob ein Programmcode eine oktale Konstante enthält oder nicht. Noch einfacher zu prüfen ist Regel 14.4, die die Benutzung des Schlüsselworts goto verbietet.

Nicht alle Regeln sind so leicht zu prüfen wie MISRA-Regel 7.1. Beispielsweise fordert MISRA-Regel 14.7, dass seine Funktion nur einen Ausgang haben darf, und zwar am Ende der Funktion („A function shall have a single point of exit at the end of the function“). Es darf also höchstens eine Return-Anweisung in einer Funktion geben und diese Return-Anweisung muss am Ende der Funktion stehen. Die Prüfung dieser Regel erfordert syntaktische Mustererkennung, denn die return-Anweisungen in einer Funktion müssen gezählt werden, was zwar ein gewisses Gedächtnis der Prüffunktion voraussetzt, aber alles in allem nicht schwierig ist, weil kein tiefergehendes Verständnis des Programms erforderlich ist wie beispielsweise eine Analyse der möglichen Pfade, die die Programmausführung nehmen kann.

Artikelfiles und Artikellinks

(ID:46497561)