Statische Code-Analyse in CI/CD-Prozessen Agile und sichere Embedded-Software-Entwicklung
Innerhalb von CI/CD-Prozessen, sprich Continuous Integration und Deployment, spielt Qualitätssicherung eine zentrale Rolle. immerhin sollen diese agilen Methoden besseren Code und leichtere Fehlerbeseitigung gewährleisten. Besonders im Embedded-Umfeld kommt es dabei darauf an, die Entwickler frühzeitig auf Fehler oder Abweichungen von gesetzten Standards hinzuweisen.
Anbieter zum Thema

Agile Entwicklungsmethoden haben sich bereits seit geraumer Zeit in allen Bereichen der Software-Entwicklung etabliert. Besonders die Prinzipien der Continuous Integration (CI) und des Continuous Deployment haben sich zu Quasistandards entwickelt.
Der Gedanke dahinter: Je öfter jeder Entwickler seinen Beitrag in den Gesamtcode einbringt, desto einfacher sind Fehlersuche und -beseitigung. Damit steigt die Qualität der Software, was wiederum eine Kernforderung des Agilen Manifests erfüllt: „Liefere funktionierende Software regelmäßig innerhalb weniger Wochen oder Monate und bevorzuge dabei die kürzere Zeitspanne.“
Der wichtigste Unterschied zwischen CI und CD ist – salopp gesagt – der Punkt, an dem die Arbeit der Entwickler als erledigt betrachtet wird. Bei CI muss der Codebeitrag eines Entwicklern, die so genannte Integration, in die gemeinsame Codebasis (Mainline) so integriert werden können, dass ein erfolgreicher Build möglich ist.
Schlägt der Build fehl, muss der Fehler mit höchster Priorität gefunden und beseitig werden. Hier gilt die Regel, dass „fixing the build“ Vorrang vor allem anderen hat. Bei CD trifft dieses Prinzip ebenfalls zu. Allerdings endet der Prozess nicht mit dem erfolgreichen Build der Mainline, sondern mit der Aulieferung an den Kunden oder Anwender.
Funktionierende, bessere Software
Neben der Geschwindigkeit der Integration spielt also das Vermeiden von Fehlern eine entscheidende Rolle in diesem Konzept. Ein weit verbreitetes Vorgehen ist, dass die Entwickler ihre Integration frühzeitig testen, in der Regel noch am eigenen Arbeitsplatz. Gelingt dort ein Test-Build, kann die Integration in die Mainline aufgenommen werden. Um Fehler und Standardverletzungen nicht zu übersehen, sind drei Punkte wichtig:
- 1. Jede Integration muss vor dem Einchecken in der Mainline hinreichend auf Fehler und Standardkonformität überprüft werden;
- 2. Der definierte Integrationsprozess muss zu jeder Zeit eingehalten werden;
- 3. Die einzelnen Schritte sind so weit als möglich zu automatisieren.
Die Automatisierung nimmt hier eine zentrale Rolle ein. Martin Fowler, einer der wichtigsten Köpfe hinter der Continuous Integration, postuliert: „Die Continuous Integration setzt ein hohes Maß an Tests voraus, die als Automatismus in die Software integriert sind.“ Denn jedes manuelle Eingreifen ist eine potenzielle Fehlerquelle, die soweit möglich vermieden werden sollte.
Für diese Anforderungen bietet sich die statische Code-Analyse an. Das Prinzip dieses Ansatzes: Aus dem Code wird ein Modell erzeugt, in dem alle Daten- und Steuerungsströme durchlaufen werden können. Über definierte Checker lassen sich so Fehler wie Buffer Overruns oder Null-Pointer-Dereferenzierungen erkennen. Auch Datenströme aus unsicheren, nicht validierten Quellen (Tainted Data) werden aufgezeigt. Zudem ist es möglich, auch Abweichungen von Programmierstandards aufzuspüren.
Static Code Analysis Tools, zu denen auch CodeSonar zählt, sind ferner in der Lage, dieses Verfahren auch auf Binärcode anzuwenden. Vor allem im Embedded-Bereich wird diese Möglichkeit immer wichtiger. Denn viele Komponenten – meist Bibliotheken und Tool-Kits – werden heute nicht mehr Inhouse entwickelt, sondern aus externen Quellen bezogen.
Ein erheblicher Teil dieses Codes liegt nur in binärer Form vor und entzieht sich damit einer manuellen Überprüfung. Die statische Analyse ergänzt das dynamische Testing um die Möglichkeit, auch nichtlauffähige Codeteile zu untersuchen sowie Codebereiche zu analysieren, die im Testing unter Umständen nicht durchlaufen werden.
Geringer Aufwand und Automatisierung
Innerhalb des Software Delevopment Lifecycles (SDLC) kann die statische Analyse an zwei Stellen zum Einsatz kommen: Am Arbeitsplatz des Entwicklers, um die Code-Qualität bereits vor dem Test-Build sicherzustellen. Hier gibt die statische Analyse den Entwicklern ein sofortiges Feedback, noch während der Code geschrieben wird. Die Warnungen ähneln der Ausgabe des Compilers, die Codequalität kann also sehr zeitnah und mit geringem Aufwand verbessert werden.
Am Build-System der Mainline geht es darum, die Integration nochmals genauer auf Fehler zu überprüfen. Und auch Probleme zu finden, die das dynamische Testing nicht erkennen kann. In beiden Szenarien lassen sich professionelle Tools wie CodeSonar nahtlos in die Tool-Chain integrieren und die Analysen automatisieren.
Dabei gilt es aber darauf zu achten, die Analysen in einem angemessenen Umfang durchzuführen. Denn neben der schnellen und häufigen Integration ist die Build-Zeit ein wichtiger Aspekt der CI. Build-Zeiten von mehreren Stunden wiedersprechen dem Agilitätsprinzip. Um zügig zu neuen Builds zu kommen, können die Analysen in verschiedenen Entwicklungsphasen mit unterschiedlichem Umfang eingebunden werden.
Bei der Analyse am Arbeitsplatz muss meist die Detailtiefe bei Analyse und Testing hinter der Geschwindigkeit zurückstecken. Deshalb ist es sinnvoll, hier nur die wichtigsten Checker zu nutzen, zum Beispiel sicherheitsrelevante Fehler wie Buffer Overflows oder Abweichungen von Programmierstandards. Die ausführlichen Tests und Analysen erfolgen an der vollständigen Codebasis. Hier steht mehr Zeit zur Verfügung.
Für die Suche nach möglichen Tainted-Data-Angriffen oder Parallelitätsproblemen ist diese Phase optimal geeignet. Auch dabei sollte man jedoch die Build-Time im Blick behalten. Unter Umständen kann es sinnvoll sein, auch auf dem Build-System nur eine Auswahl der benötigten Tests und Analysen durchzuführen, um tiefgreifende Tests in einer zweiten Stufe umzusetzen. Der Vorteil bei diesem Ansatz ist, dass der Build mit den aktuellen Commits schnell im Repository zur Verfügung steht und dennoch eine intensive Qualitätssicherung vor dem Deplyoment gewährleistet werden kann.
Fazit
Continuous Integration und Continuous Deployment haben sich in der agilen Software-Entwicklung bewährt, um Funktionen schnell bereitzustellen. Der Ansatz erlaubt einen schlanken Entwicklungsprozess, indem ein großer Teil der Routinetätigkeiten in kleine, überschaubare Portionen aufgeteilt wird. Der Erfolg hängt jedoch entscheidend von der Qualität und Fehlerfreiheit der Integrations ab.
Je früher Bugs erkannt und beseitigt werden, desto geringer ist das Risiko fehlgeschlagener Builds – und damit die Gefahr, unangemessen viel Zeit und Ressourcen mit der Fehlersuche zu vergeuden. Die statische Analyse kann innerhalb des agilen SDLC helfen, die Entwicklung und die Time to Market signifikant zu beschleunigen. Und gleichzeitig die Qualität der Software zu verbessern.
* * Mark Hermeling, Senior Director Product Marketing bei GrammaTech, Inc.
(ID:45513621)