Für gewöhnlich sind Systeme, die Sicherheitsfunktionen ausführen, sehr komplex und machen es in der Praxis unmöglich, jeden Fehlermodus vollständig zu ermitteln oder jedes mögliche Verhalten zu testen. Auch wenn es schwer ist, die Sicherheitsleistung vorherzusagen, sind Tests unerlässlich. Die Herausforderung besteht darin, das System so zu entwerfen, dass Fehler entweder vermieden oder aber beherrscht werden, wenn sie entstehen. Mit dem Trend zu zunehmender Komplexität, Softwaregehalt und mechatronischer Implementierung in Fahrzeugen steigt auch das Risiko von systematischen Fehlern und zufälligen Hardwareausfällen. Neue Funktionalität verstärkt die Notwendigkeit, sichere Systementwicklungsprozesse zu entwickeln und den Nachweis zu erbringen, dass alle erforderlichen Sicherheitsziele erfüllt wurden.
Automotive Safety Integrity Level (ASIL) - wie in der Norm ISO 26262 definiert - ist eine von vier Stufen (1-4 in, A-D in ISO 26262) zur Spezifizierung der notwendigen Sicherheitsmaßnahmen zur Vermeidung eines unangemessenen Restrisikos. D stellt die strengste Stufe, 1 oder A die am wenigsten strenge Stufe dar. Es ist zu beachten, dass der Sicherheitsintegritätslevel eine Eigenschaft einer bestimmten Sicherheitsfunktion ist und keine Eigenschaft des gesamten Systems oder einer Systemkomponente. Jeder Sicherheitsfunktion in einem sicherheitsbezogenen System muss ein geeignetes Sicherheitsintegritätslevel zugewiesen werden. Nach ISO 26262 wird das Risiko einer jeden Gefahrensituation anhand dieser Attribute bewertet:
- Häufigkeit der Situation – „Exposition“
- Auswirkung des möglichen Schadens – „Schweregrad“
- „Beherrschbarkeit“
Abhängig von den Werten dieser drei Attribute wird der entsprechende Sicherheitsintegritätsgrad für einen bestimmten Funktionsfehler bewertet. Dies bestimmt den Gesamt-ASIL für eine bestimmte Sicherheitsfunktion durch C/C++-Testfunktionalität.
Laut ISO-26262-Norm müssen eine Reihe von verschiedenen Methoden, die im Software-Entwicklungslebenszyklus von Sicherheitsfunktionen zum Einsatz kommen, die ASIL-Anforderungen erfüllen. Mit C/C++test erhalten Entwickler in der Automobilindustrie Support zur Erfüllung der ISO 26262 Verifizierungs- und Validierungsanforderungen. Eine breite Palette von Testmethoden wie statische Analyse, Daten- und Kontrollfluss-Analyse, Unit-Tests, Anwendungsüberwachung, Workflow-Komponenten und Peer-Code-Review-Prozess zusammen mit den konfigurierbaren Testberichten, die ein hohes Maß an Details enthalten, erleichtert die Arbeit, die für den Software-Verifizierungsprozess erforderlich ist.
Eine richtig umgesetzte Programmierrichtlinie kann ganze Klassen von Programmierfehlern durch das Festlegen von präventiven Kodierungskonventionen verhindern. Um die Befolgung einer solchen Richtlinie zu überprüfen, führt C/C++test eine statische Codeanalyse aus. Gruppen- oder unternehmensspezifische Richtlinien können etabliert werden, indem Benutzer ihre eigenen Regelsätze definieren; die Analyseberichte sind in verschiedenen Formaten einschließlich HTML und PDF möglich.
Laufzeitfehler ohne Ausführungssoftware identifizieren
Bei der Flussanalyse analysieren die Werkzeuge den Quellcode, um den zugrunde liegenden Kontrollfluss und den Datenfluss des Codes zu verstehen und zu ermitteln, ob diese Pfade bestimmte Kategorien von Laufzeitfehlern auslösen könnten. Zu den entdeckten Schwachstellen gehören die Verwendung von nicht initialisiertem oder ungültigem Speicher, die Nullzeiger-Dereferenzierung, Array- und Pufferüberläufe, Teilen durch Null, Speicher- und Ressourcenlecks sowie verschiedene Arten von totem Code. Fehler aufzudecken, ohne den Code auszuführen, ist besonders wertvoll für embedded Code, wo eine detaillierte Laufzeitanalyse für solche Fehler oft nicht effektiv oder gar nicht möglich ist. Indem C/C++test eine vollständige Verfolgung des Pfads für jeden potenziellen Fehler in der IDE des Entwicklers bereitstellt, vereinfacht es die Fehleranalyse enorm. Automatische Querverweise zum Code helfen dem Benutzer, schnell zu jedem beliebigen Punkt im markierten Analysepfad zu springen (Bild 1).
Rationalisierte Codeüberprüfung
Der Code-Review ist die effektivste Methode zum Auffinden von Bugs, wird aber oft nur unzureichend genutzt, weil davon ausgegangen wird, dass das sehr arbeitsintensiv ist. Tools wie der DTP Change Explorer von Parasoft ermöglichen die bequeme Analyse von Quellcode-Deltas zwischen bestimmten Meilensteinen oder Punkten in der Entwicklung. Die Überschneidung von Code-Delta-Informationen mit Ergebnissen der statischen Analyse oder von Unit-Tests hebt den traditionellen Code-Review-Prozess auf eine völlig neue Ebene.
Anwendung auf Speicherprobleme überwachen
Der bekannteste Ansatz, um ernsthafte speicherbezogene Fehler zu beheben ohne falsch-positive Ergebnisse, ist die Überwachung des Anwendungsspeichers. Dabei wird die laufende Anwendung ständig auf bestimmte Problemklassen wie Speicherlecks, Nullzeiger, nicht initialisierter Speicher und Pufferüberläufe überwacht, und die Ergebnisse sind sofort nach Abschluss der Testsitzung sichtbar.
Ohne moderne und zeitaufwändige Testaktivitäten zu benötigen, durchläuft die instrumentierte Anwendung die Standardfunktionstests, und alle vorhandenen Probleme werden markiert. Die gesammelten Probleme werden direkt in der IDE des Entwicklers angezeigt, zusammen mit den zum Verstehen und Beheben des Problems notwendigen Details, einschließlich Speicherblockgröße, Array-Index und Allokations-/Deallokations-Stack-Trace.
Mithilfe von Abdeckungsmetriken während der Ausführung der Anwendung lässt sich feststellen, welcher Teil der Anwendung getestet wurde, und die Feinabstimmung des Satzes von Regression-Unit-Tests ausführen. Mit dieser Laufzeitfehler-Erkennung lassen sich komplexe, speicherbezogene Probleme durch einfache Funktionstests identifizieren, beispielweise:
- Speicherlecks, Nullzeiger, nicht initialisierter Speicher und Pufferüberläufe,
- Erfassen der Codeabdeckung von Anwendungsläufen
- Höhere Genauigkeit der Testergebnisse durch Ausführen der überwachten Anwendung in einer realen Zielumgebung
Unit- und Integrationstests mit Abdeckungsanalyse
Die auf KI basierende Automatisierung von C/C++test ermöglicht deutlich effizientere Tests von Richtigkeit und Zuverlässigkeit sowohl bei neu entwickeltem als auch Code aus Altbestand. C/C++test generiert automatisch vollständige Tests, einschließlich Testtreibern und Testfällen für einzelne Funktionen, rein in C- oder C++-Code in einem CppUnit-ähnlichen Format. Mithilfe dieser automatisierten Tests können potenzielle Zuverlässigkeitsprobleme aufgedeckt werden. Spezifische GUI-Widgets vereinfachen das Erstellen und Verwalten von Tests. Mit einem grafischen Testfall-Assistent können Entwickler funktionale Blackbox-Tests für ausgewählte Funktionen schnell erstellen, ohne dass sie sich um deren Innenleben oder Embedded-Datenabhängigkeiten kümmern müssen. Ein Datenquellen-Assistent hilft bei der Parametrisierung von Testfällen und Stubs und ermöglicht einen größeren Testumfang und eine höhere Testabdeckung bei minimalem Aufwand. Die Testdurchführung und -analyse erfolgt zentral im Testfall-Explorer, der alle vorhandenen Projekttests zusammenfasst und einen klaren Pass/Fail-Status liefert. Speziell bei der Unterstützung der automatisierten kontinuierlichen Integration und des Testens sowie der „Test as you go“-Entwicklung ist das eine große Hilfe.
Sowohl automatisch generierte als auch handgeschriebene Testfälle ermöglichen die Generierung einer Regressionstestbasis. Dabei wird das vorhandene Softwareverhalten über Testaussagen erfasst, die durch die automatische Aufzeichnung der Testergebnisse zur Laufzeit erzeugt werden. Im Zuge der Weiterentwicklung der Codebasis führt C/C++test diese Tests erneut aus und vergleicht die aktuellen Ergebnisse mit denen des ursprünglich erfassten „Golden Set“. C/C++test lässt sich leicht so konfigurieren, dass verschiedene Ausführungseinstellungen, Testfälle und Stubs verwendet werden können, um das Testen in verschiedenen Kontexten zu unterstützen, z. B. in verschiedenen Phasen der kontinuierlichen Integration, beim Testen unvollständiger Systeme oder beim Testen bestimmter Teile vollständiger Systeme.
Ein multimetrischer Testabdeckungsanalysator, einschließlich Anweisungs-, Verzweigungs-, Funktions-, Aufruf- und MC/DC Abdeckung, hilft dem Benutzer, die Wirksamkeit und Vollständigkeit der Tests zu beurteilen. Die Testabdeckung wird durch Code-Hervorhebung für alle unterstützten Abdeckungsmetriken in der grafischen Benutzeroberfläche oder durch farbcodierte Code-Listing-Berichte dargestellt. Zusammenfassende Abdeckungsberichte mit Datei-, Klassen- und Funktionsdaten sind in vielen Formaten erstellbar (Bild 2).
Konfigurierbares Reporting
Es ist möglich, die Reports von C/C++test im HTML-, PDF- und benutzerdefinierten Format über GUI-Steuerelemente oder eine Optionsdatei zu konfigurieren. Die Standardberichte enthalten eine Pass/Fail-Zusammenfassung von Codeanalyse- und Testergebnissen, eine Liste der analysierten Dateien und eine Zusammenfassung der Codeabdeckung. Alle Reports lassen sich so anpassen, dass sie eine Auflistung aktiver statischer Analyseprüfungen, eine erweiterte Testausgabe mit dem Pass/Fail-Status einzelner Tests, Parameter von Trenddiagrammen für wichtige Metriken und vollständige Codelisten mit Farbcodierung aller Codeabdeckungsergebnisse enthalten. Erstellte Berichte können automatisch per E-Mail verschickt werden, auf Grundlage einer Vielzahl von rollenbasierten Filtern. C/C++test liefert die Daten direkt an die Entwickler, die für den als fehlerhaft markierten Code verantwortlich sind, und an deren IDE mit vollständigen Querverweisen.
Für Support der Manager bei der Bewertung und Dokumentation von Trends ermöglicht ein zentralisiertes Berichtswesen Echtzeiteinblicke in den Qualitätsstatus und die Prozesse. Anhand dieser Daten lässt sich auch feststellen, ob zusätzliche Maßnahmen erforderlich sind, um interne Ziele zu erreichen oder die Befolgung gesetzlicher Vorschriften nachzuweisen (Bild 3).
DTP
Es gibt die Möglichkeit, Code-Analysen und Testergebnisse, Abdeckungsanalysen und andere C/C++-Testdaten an Parasoft DTP zu senden, um sie mit Daten zu korrelieren, die von Analysatoren anderer Anbieter, der Versionskontrolle, der Fehlerverfolgung und anderen Infrastrukturkomponenten erzeugt und von DTP verarbeitet werden. Das Ergebnis sind umsetzbare, intelligente Analysen, die nicht nur einen Einblick in das mit der getesteten Anwendung verbundene Risiko bieten, sondern auch die für die Einhaltung der ISO 26262 notwendigen Rückverfolgbarkeit. (na)