Dass bei jedem Projekt zur Migration einer bestehenden Applikation erhebliche Zeit dafür eingeplant werden muss, die Software in ihrer neuen Inkarnation zu prüfen, steht außer Zweifel. Allerdings können die Testergebnisse immer nur so gut sein wie die Werte, die für die Tests verwendet werden. Wenn ein Verarbeitungspfad, auf dem ein Fehler auftritt, von einem Testfall nicht benutzt wird, kann es sein, dass der Defekt unentdeckt bleibt. Das Generieren neuer Testfälle aber ist teuer.
Eine sinnvolle Taktik zum Ausmerzen dieser latenten Fehler besteht darin, beim Transformieren der alten Applikation auf fortschrittliche statische Analyse-Tools zu setzen. Werkzeuge dieser Art können Defekte der eben beschriebenen Art entdecken. Sie finden dabei auch solche Bugs, die von subtilen Unterschieden zwischen den Plattformen ausgelöst werden.
Gravierende Fehler, wie etwa nicht initialisierte Variablen, Pufferüberläufe und Nullzeiger-Exceptions, werden ebenso identifiziert wie Fehler, die auf die Nichteinhaltung von Regeln zur Verwendung eines API zurückzuführen sind. Dies kann beispielsweise das doppelte Schließen eines Dateideskriptors oder ein Ressourcenleck sein.
Die besondere Stärke statischer Analyse-Tools aber liegt in der Aufdeckung von Nebenläufigkeits-Defekten wie etwa Data Races, die sich mit traditionellen Prüfmethoden nur äußerst schwierig feststellen lassen. Wenn die Tools einen Defekt finden, melden sie ihn mitsamt dem Pfad, der zum Triggern des Fehlers führt (ggf. auch mehrerer Pfade). In Bild 1 ist ein Screenshot von dem Statische-Analyse-Tool CodeSonar wiedergegeben. Die Grafik zeigt die Zahl der Probleme, die in verschiedenen Versionen ein und desselben Programms aufgedeckt wurden, und vermittelt dem Anwender einen Einblick, wie sich der Code im Lauf der Zeit entwickelt hat.
Solche Analyse-Tools können außerdem nach dem Top-Down-Prinzip eingesetzt werden und dabei jene Teile des Codes ermitteln, die am riskantesten sind. Bild 2 zeigt beispielsweise eine Treemap-Darstellung. Die Rechtecke stehen hier für Module, Untermodule, Kompilierungseinheiten und einzelne Funktionen. Die Größe der Rechtecke richtet sich nach der Zahl der Codezeilen des jeweiligen Elements, während die Intensität der Farbe die Zahl der Probleme symbolisiert, die die statische Analyse im jeweiligen Element gefunden hat. Die riskantesten Teile des Codes lassen sich damit einfach ermitteln.
Selbstverständlich kann die statische Analyse kein Ersatz für rigoroses Testen sein. Beide Verfahren ergänzen einander vielmehr, und als Optimum ist eine Methode anzusehen, die die statische Analyse mit der dynamischen Analyse (z.B. dem Testen) kombiniert. Denn erst eine schnelle Identifizierung von latenten Software-Defekten macht die Wiederverwendung von Software wirtschaftlich besonders effektiv.
Literatur
[1] Xuejun Yang, Yang Chen, Eric Eide, John Regehr: Finding and understanding bugs in C compilers, 2011. http://www.cs.utah.edu/~regehr/papers/pldi11-preprint.pdf [2] Cindy Rubio-González, Ben Liblit: Expect the Unexpected: Error Code Mismatches Between Documentation and the Real World, 2010. http://www.eecs.berkeley.edu/~rubio/includes/paste10.pdf
Der Autor
Paul Anderson |
---|
ist Vice President of Engineering bei GrammaTech, einem auf die statische Analyse spezialisierten Spin-off der Cornell University. Anderson hat ein Studium am King‘s College der University of London mit einem Bachelor-Diplom abgeschlossen und außerdem an der City University London im Fach Informatik promoviert. |