Company Topimage

Parasoft® Deutschland GmbH

http://www.parasoft.de
Firma bearbeiten

10.06.2021

Embedded SW+KI: Mit künstlicher Intelligenz die Ergebnisse der statischen Analyse priorisieren

Die Einbringung statischer Analysetools in den Entwicklungsprozess ist unter Umständen eine schwierige Aufgabe. Suboptimale Konfigurationen können Fehlalarme auslösen und große Probleme schaffen und im schlimmsten Fall dazu führen, dass Entwicklungsteams komplett davon Abstand nehmen, die statische Analyse in ihren Arbeitsablauf zu integrieren. Jetzt aber gibt es die Option für Teams, mithilfe von künstlicher Intelligenz (KI) automatisch jene Warnmeldungen der statischen Analyse zu identifizieren, die auf die größten Risiken hinweisen und um die man sich folglich am dringendsten kümmern muss. (Bildquelle: Shutterstock-701349271)

Die statische Programmanalyse wendet kompilierbare statische Techniken an, um berechenbare Näherungen des dynamischen Verhaltens zu prognostizieren, das sich zur Laufzeit, also während der Verarbeitung eines Programms einstellt [1]. Man setzt die statische Analyse in großem Umfang zur Abwendung von Fehlern bei der Entwicklung sicherheitskritischer Systeme ein [2]. Mit ihrer Hilfe lässt sich das Vertrauen darin stärken, dass ein Programm ohne Fehler ausgeführt wird. Deshalb wird sie von einigen Safety-Normen vorgeschrieben und ist bei der Entwicklung vieler Produkte zwingend anzuwenden.

Aber die Einbringung der statischen Analyse in den Entwicklungsprozess ist keine einfache Sache, was hauptsächlich an der großen Zahl von Falsch-Positivmeldungen in der typischen Ausgabe eines statischen Codeanalyse-Tools liegt [3].

 

Dieser Beitrag beschreibt eine Methode, um mithilfe von ML (Machine Learning) die separaten Analyseergebnisse (wobei jedes Ergebnis einem möglichen Fehler entspricht) in zwei Kategorien einzuordnen: Die eine umfasst Fehler, die mit größter Wahrscheinlichkeit eine Abhilfemaßnahme erfordern, während die andere Kategorie solche Fehler enthält, die das Team sehr wahrscheinlich ignorieren und bei künftigen statischen Analyseläufen unberücksichtigt lassen möchte. Zum Einsatz kommen Metadaten, die mit jedem statischen Analyseergebnis verbunden sind, z.B. Autor, Regel, Modul, Zweig, als Input für das Modell und für den Versuch vorherzusagen, ob der Anwender das gefundene Problem verwerfen (d. h. künftig ignorieren) oder beheben will.

 

Treiber für diese Untersuchung ist das sich wiederholende Szenario, das wir in Unternehmen beobachten, die versuchen, die statische Code-Analyse in ihren Software-Entwicklungsprozess zu integrieren – und aufgrund der notwendigen Zeit, um sich durch die ersten Berichte eines statischen Analysators durchzuarbeiten, daran scheitern. Die in diesem Artikel beschriebene Methode wurde bei Parasoft evaluiert, in ein Produkt umgesetzt und als Zusatzfunktion zu statischen Codeanalyse-Engines veröffentlicht. Der erste Teil des Beitrags zeigt auf, wie diese Methode anhand der Metadaten der Ergebnisse die wichtige Befunde in der Ausgabe eines statischen Analysetools schnell ermittelt. Es folgt die Evaluierung der Methode an einem großen proprietären, kommerziellen Produkt, für das eine lange Historie statischer Analysen existiert.

 

Das Problem der übergroßen Zahl von Falsch-Positiv-Meldungen in den Ausgaben typischer statischer Analysetools ist allgemein bekannt. Es gilt als das größte Hindernis für die höhere Akzeptanz der statischen Codeanalyse in der Softwareentwicklungs-Branche [3, 4]. Für die vielen Falsch-Positiv-Meldungen wurden zahlreiche Gründe ermittelt: Zum Beispiel kann die Zahl der zur Auswahl stehenden Normen, Regeln, Praktiken und Empfehlungen übermäßig groß sein. Das macht es für die Entwickler oftmals schwierig, sich darin zurechtzufinden und sich einen Reim darauf zu machen. Hinzu kommt, dass verschiedene Entwicklerteams unterschiedliche und stark variierende Anforderungen an die nicht funktionsbezogenen Qualitäten ihres Quellcodes stellen. Das heißt in der Praxis: Es ist nicht möglich, einen Satz an Empfehlungen zu definieren, der für alle Entwicklerteams gilt. Jedes Team definiert Falsch-Positiv-Meldungen anders, und so kommt es, dass statische Codeanalyzer eine gefühlt große Zahl Falschmeldungen ausgeben – darum verzweifeln  Teams oftmals an der Nutzung der statische Analyse.

 

Vorhersage von Falsch-Positiv-Meldungen per ML

Wir schlagen hier eine Methode vor, um die Befunde in der Ausgabe eines statischen Analysetools entweder als etwas zu klassifizieren, was das Team sehen will, oder vielmehr als etwas, was das Team nicht weiter beachten möchte. Hierzu wird eine kleine Zahl von Resultaten geprüft, um anhand der zu diesen Ergebnissen gehörenden Metadaten einen Classifier zu konstruieren. Dann bewerteten wir dessen Leistungsfähigkeit auf der Basis von Daten aus einem bei Parasoft entwickelten, proprietären Projekt.

 

Versuchsaufbau

Das Experiment war wie folgt angelegt: Um zunächst die „Ground Truth“ zu etablieren, also zu bestimmen, ob eine Fehlermeldung gerechtfertigt ist oder nicht, kamen die Daten aus zwei Durchläufen desselben statischen Codeanalyse-Tools zum Einsatz zusammen mit Informationen darüber, welche Ergebnisse vom Team verworfen und welche für eine weitere Untersuchung vorgemerkt wurden. Dann wurde eine kleine Zahl von Ergebnissen aus dem ersten Durchlauf erfasst, und das ML-Modell an diesem begrenzten Umfang an Daten trainiert. Sämtliche übrigen Daten fanden Verwendung als Testdaten, um die Leistungsfähigkeit des ML-Modells zu beurteilen.

 

Versuchsdaten

Einbezogen wurden die Daten aus einem der großen internen Projekte von Parasoft, für das sich eine lange Historie statischer Analyseergebnisse angesammelt hatte. Einige dieser Befunde waren im Laufe der Jahre entfernt und andere verworfen worden. Ein Vergleich der Ergebnisliste in zwei Momentaufnahmen des Projekts zeigte auf, welche Befunde entfernt worden waren. Der resultierende Datenbestand enthielt 31.730 Befunde, von denen 16.706 entfernt worden waren (diese wurden im Rahmen des Experiments als echte Fehler betrachtet). Jede Datenprobe umfasste 21 Merkmale. Jedes Merkmal wurde in Kategorien umgewandelt und fakturiert, um für jede eine Ganzzahl zu ermitteln. Versuche mit den folgenden Classifiern führten zu den angegebenen Genauigkeiten:

 

Bedingt durch das Wesen der vorliegenden Daten ist es in vielen Fällen besser, die Zahl der echten Fehler zu hoch und die der wahrscheinlich verworfenen Befunde zu niedrig zu prognostizieren. So lässt sich die Chance minimieren, dass ein echter Fehler fälschlicherweise ignoriert wird. Zur Bewertung der Classifier-Performance bei wechselnden Wahrscheinlichkeitsschwellen wurde eine ROC-Kurve (Receiver Operating Characteristic / Betriebskennlinie des Empfängers) [9] erstellt.

Im nächsten Schritt erfolgte die Untersuchung der ROC-Kurve eines Random-Forest-Classifiers, der mit unterschiedlich vielen Datenproben in der Trainingsmenge (N = 20, 40, 200) trainiert wurde. Die Testmenge enthält sämtliche verbliebenen Proben.

 Bewertung der Ergebnisse, Grenzen der Methoden und to Dos

Wie wir nachweisen konnten, lassen sich die Metadaten der von der statischen Analyse generierten Befunde nutzen, um diese Befunde rasch in zwei Klassen (für die Behebung /  das Verwerfen empfohlen) einzuordnen. Nach manueller Überprüfung einer überschaubaren Anzahl von Ergebnissen (von einem Entwickler in weniger als einem Tag zu bewältigen), können die verbleibenden Befunde auf der Basis der Wahrscheinlichkeit, dass sie in die eine oder die andere Klasse einzuordnen sind, nach ihrer Priorität kategorisiert werden.

 

Unsere Pläne für die nächste Zukunft sehen vor, syntaktische und semantische Informationen im Zusammenhang mit dem Codeabschnitt hinzuzufügen, aus dem der Befund stammt. Eingezogen werden sollen auch die historischen Daten von Projekten, in denen solche Daten verfügbar sind.

 

 Autor: Leonid Borodaev, R&D bei Parasoft

Referenzen:

  [1]

F. Nielson, H. R. Nielson and C. Hankin, Principles of Program Analysis, Berlin: Springer-Verlag, 1999.

[2]

P. Feiler, J. Goodenough, A. Gurfinkel, C. Weinstock and L. Wrage, Four Pillars for Improving the Quality of Safety-Critical Software-Reliant Systems, 2013.

[3]

A. Bessey, K. Block, B. Chelf, A. Chou, B. Fulton, S. Hallem, C. Henri-Gros, A. Kamsky, S. McPeak and D. Engler, "A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World," Communications of the ACM, vol. 53, no. 2, pp. 66-75, February 2010.

[4]

L. Flynn, W. Snavely, D. Svoboda, N. VanHoudnos, R. Qin, J. Burns, D. Zubrow, R. Stoddard and G. Marce-Santurio, "Prioritizing Alerts from Multiple Static Analysis Tools, using Classification Models," in 2018 ACM/IEEE 1st International Workshop on Software Qualities and their Dependencies, Gothenburg, Sweden, 2018.

[5]

Y. Freund and R. Schapire, "A Decision-Theoretic Generalization of On-Line Learning and an Application to Boosting," Journal of Computer and System Sciences, vol. 55, no. 1, pp. 119-139, 1997.

[6]

"Bagging meta-estimator," [Online]. Available: https://scikit-learn.org/stable/modules/ensemble.html#bagging-meta-estimator. [Accessed 27 March 2020].

[7]

L. Breiman , "Random Forests," Machine Learning, vol. 45, no. 1, pp. 5-32, 2001.

[8]

"Forests of Randomized Trees," [Online]. Available: https://scikit-learn.org/stable/modules/ensemble.html#forests-of-randomized-trees. [Accessed 27 March 2020].

[9]

T. Fawcett, "An introduction to ROC analysis," Pattern Recognition Letters, p. 861–874, 2006.