Ausprägungen der dynamischen Codeanalyse

Transcription

Ausprägungen der dynamischen Codeanalyse
MÖGLICHKEITEN UND GRENZEN IN
DER DYNAMISCHEN CODEANALYSE
VON C++ SOFTWARE
Von Matthias Neumann
19.01.2015
Inhaltsangabe
• Einleitung
• Ausprägungen der dynamischen Codeanalyse
• Debugging
• Logging
• Testing
• Profiling
• Profiling im Detail
• Technische Realisierungsmöglichkeiten
• Messkriterien für Profiling
• Auswirkungen auf das zu analysierende Programm
2/35
19.01.2015
Inhaltsangabe
3/35
• Abgrenzung zur statischen Codeanalyse
• Definitionder statischen Codeanalyse
• Durch Menschen
• Durch automatisierte Werkzeuge
• Vergleich von dynamischer und statischer Codeanalyse
• Vor- und Nachteile der statischen Codeanalyse
• Vor- und Nachteile der dynamischen Codeanalyse
• Fazit
19.01.2015
EINLEITUNG
4/35
19.01.2015
5/35
Einleitung
• Komplexität von Software wächst stetig
• Trotz Komplexität muss Qualität gewährleistet werden
• Mängel müssen so früh wie möglich lokalisiert werden
• Dynamische und statische Codeanalyse unterstützen bei der
Fehlersuche
• Dynamische Codeanalyse untersucht Laufzeit-Fehler
19.01.2015
6/35
• Dynamische Codeanalyse brisantes Thema
• Jährliche Konferenz (“Workshop on Dynamic Analysis”)
• Relevant bei INFORM für ein Projekt am Frankfurter Flughafen
• Dabei müssen Zeitvorgaben bei der Verarbeitung von xml-
Telegrammen eingehalten werden
• In der Ausarbeitung wurden deshalb die Möglichkeiten der
dynamischen Codeanalyse evaluiert
19.01.2015
AUSPRÄGUNGEN
der dynamischen Codeanalyse
7/35
19.01.2015
Ausprägungen
8/35
Allgemeines
• Jegliche Analyse des Programms, die während der Laufzeit
stattfindet
• Durch die Ergebnisse dieser Analyse können Schwachstellen
im Code lokalisiert werden
19.01.2015
Ausprägungen
9/35
Debugging
• Ist ein Hilfsprogramm, das die Variablenwerte darstellt und
schrittweise den Programmcode durchläuft
• Aufruflisten geben Informationen über Aufrufhierarchien der
Funktionen
• Option beim Kompilieren unter GCC
• Debug-Modus unter Visual Studio
• Zusätzliche Informationen werden im Executable hinterlegt
(Dateigröße nimmt zu)
19.01.2015
Ausprägungen
Logging
• Logger protokolliert die Aktionen eines Programms
• Auch nach Absturz Laufzeitinformationen
• Ausgabe der Logs benötigt Ressourcen (IO)
10/35
19.01.2015
Ausprägungen
11/35
Testing
• Ausführung des Programms mit dem Ziel Fehler zu finden
• Black-Box-Testing
• Tester kennt innere Strukturen nicht
• Durch Eingaben werden die Ausgaben geprüft
• Glass-Box-Testing
• Tester kennt interne Logik
• Tester schreibt Tests, die bestimmte Passagen des Quellcodes
durchlaufen
19.01.2015
Ausprägungen
12/35
Profiling
• Externes Werkzeug
• Misst bestimmte Laufzeitdaten eines Programmes, wie z.B.
• die Anzahl der Aufrufe einer Funktion
• Laufzeiten von Funktionen
• Speicherauslastungen
• Speicherlecks
• Codeüberdeckungen
19.01.2015
PROFILING
im Detail
13/35
19.01.2015
Profiling
14/35
Technische Realisierungsmöglichkeiten
• Manuelle Instrumentierung
• Zusätzliche Instruktionen werden dem Programm hinzugefügt
• Findet zeitlich vor dem Kompilieren statt
• Programmintern werden Werte ermittelt, die nach außen getragen
werden
 Muss eigenständig implementiert
+ Stark individualisierbar
19.01.2015
ProfilingTechnische Realisierung
15/35
• Instrumentierung zur Compilezeit
• Wie manuelle Instrumentierung, aber mit generiertem Code
• Compiler fügt zusätzliche Instruktionen vor dem Kompilieren ein
• Typischerweise werden Funktionsaufrufe und Hierarchien
gemessen und aufbereitet
• Bspw: Visual Studio
 Eingeschränkte Individualisierbarkeit
+ Kein Programmieraufwand
19.01.2015
ProfilingTechnische Realisierung
16/35
• Binäre Instrumentierung
• Findet nach dem Kompilieren statt
• Auf binärer Ebene wird das Programm manipuliert, so dass es
Messpunkte zur Laufzeit zur Verfügung stellt
• Bspw: ATOM
 Keine Anpassungsmöglichkeiten
+ Keine Optionen beim Kompilieren
+ Kein manueller Aufwand
19.01.2015
ProfilingTechnische Realisierung
17/35
• Laufzeitinstrumentierung
• Programm läuft in einer virtuellen Maschine, die es observiert
(Funktionsaufrufe, Speicherbedarf, etc.)
• Bspw: Valgrind
 Erhebliche Einbußen in der Performanz
 Durch Virtualisierung sind Umstände anders
+ Sehr geringer Aufwand
+ Programm muss nicht manipuliert werden
19.01.2015
ProfilingTechnische Realisierung
18/35
• Sampling
• Laufendes Programm wird stichprobenartig geprüft
• „Stichproben“ werden in einer bestimmten Frequenz genommen
• „Stichproben“ enthalten Informationen über die Funktion, die aktuell
ausgeführt wird und dessen Aufrufhierarchie
• Relativer Anteil der Stichproben pro Funktion wird berechnet
+ Nahezu kein Geschwindigkeitsverlust
+ Keine Manipulation des Programms bzw. dessen Codes
 Ungenau, da nicht die Aktionen des Programms vernommen werden
19.01.2015
Profiling
19/35
Auswirkungen auf das Programm
• Instrumentierung
• Zusätzliche Instruktionen verlangsamen das Programm
• Größe des Programms nimmt zu (Dateigröße)
• Speicherverhalten während der Laufzeit verändert sich
19.01.2015
ABGRENZUNG
zur statischen Codeanalyse
20/35
19.01.2015
Abgrenzung
21/35
Statische Codeanalyse
• Quellcode wird ohne Ausführung des Programms analysiert
• Code wird in textueller Form interpretiert und bewertet
• Frühe Fehlererkennung (vor oder während des Kompilierens)
• Kann durch automatisierte Werkzeuge oder durch Menschen
stattfinden
19.01.2015
AbgrenzungStatische Codeanalyse
22/35
• Durch Entwickler
• Selten Überprüfungen auf Syntax, da sehr langwierig
(Aufgabe für automatisierte Werkzeuge)
• Analyse auf Namenskonventionen und Funktionalität
• Dazu gehören: Codeinspektionen, Walkthroughs, Schreibtischtests,
Pair-Programming
19.01.2015
23/35
• Durch Werkzeuge
• Ermitteln Metriken, Vererbungen, syntaktische Fehler,
Abhängigkeiten, etc. indem sie den Quellcode scannen
• Ähnliche Aufgaben wie Compiler
• Liefern eine aufbereitete Zusammenfassung der Ergebnisse bzw.
Warnungen
• Visualisierungen, wie Klassendiagramme oder Nassi-
Shneidermann-Diagramme
• Oft in Entwicklungsumgebungen integriert
19.01.2015
VERGLEICH
von dynamischer und statischer Codeanalyse
24/35
19.01.2015
VergleichStatische Codeanalyse
25/35
Vorteile der statischen Analyse
+ Fehler/Warnungen beziehen sich auf eine exakte Stelle im
Code
+ Gute Integration in Entwicklungsumgebungen
• Schnelle Navigation (u.a. durch Outlining)
• Statische Typsicherheit
• Codegenerierung (Getter, Setter, Deklaration in Header, etc.)
• Automatische Vervollständigung sowie passende Vorschläge
+ Gute Externe Tools wie Lint finden viele potentielle
Schwachstellen, die der Compiler übersieht
19.01.2015
VergleichStatische Codeanalyse
26/35
Vorteile der statischen Analyse
+ Meist nur einmaliger Aufwand nötig
+ Deckt auch Teile des Codes ab, für die keine Tests formuliert
sind
19.01.2015
VergleichStatische Codeanalyse
27/35
Nachteile der statischen Analyse
 Quellcode muss verfügbar sein
 Manuelle Analyse fordert hohe Konzentration und Ausdauer
 Trotzdem möglich, dass Fehler nicht gefunden werden
 Korrekter Code kann als fehlerhaft deklariert werden
 Analyse ist nur so gut, wie die definierten Prüfregeln
 Fehler, die auf bestimmter Hardware auftreten, werden nicht
gefunden
19.01.2015
VergleichDynamische Codeanalyse
28/35
Vorteile der dynamischen Analyse
+ Quellcode nicht zwangsläufig nötig
+ Fehler im Zusammenhang mit der Hardwarekonfiguration oder
Laufzeitumgebung, werden nur in der Ausführung gefunden
+ Funktionalitäten werden geprüft
(gute Testfälle geben Sicherheit, u.a. bei Refactoring)
+ Laufzeitinformationen (wie Zeitmessungen) nur dynamisch zu
ermitteln
19.01.2015
VergleichDynamische Codeanalyse
29/35
Vorteile der dynamischen Analyse
+ Performance-Tests
+ Sicherheitslücken, wie unzulässige Speicherzugriffe, Buffer-
Overflows, etc. können entdeckt werden
+ Logging-Mechanismus möglich um auch produktive Systeme
zu observieren und Abstürze nachzuvollziehen
19.01.2015
VergleichDynamische Codeanalyse
30/35
Nachteile der dynamischen Analyse
 Komplexer und daher schwerer in bestehendes Projekt zu
integrieren
 Teilweise muss Code geschrieben werden
(manuelle Instrumentierung, Logging, Tests)
 Schlecht gewählte Testfälle garantieren keine Korrektheit
 Fehlgeschlagener Test zeigt nur Auslöser nicht Ursache
 Manipulation des Programmes bei vielen Profilingverfahren
nötig
19.01.2015
VergleichDynamische Codeanalyse
31/35
Nachteile der dynamischen Analyse
 Durch Manipulation wird Verhalten des Programms geändert
 Dadurch ist es möglich, dass Zeitmessungen unbrauchbar
werden
 Sampling bei wenigen „Stichproben“ nicht repräsentativ
19.01.2015
FAZIT
32/35
19.01.2015
Fazit
33/35
• Weder die statische noch die dynamische Codeanalyse sind
objektiv betrachtet besser als die andere
• Eher: Ergänzen sich gegenseitig
• Schließen sich nicht gegenseitig aus
• Finden meistens auch zeitlich in unterschiedlichen
Entwicklungsphasen statt
• Sinnvoll einzelne Werkzeuge und Verfahren der jeweiligen
Analysen zu kombinieren
19.01.2015
Fazit
34/35
• Während der Entwicklung Pair-Programming und Reviews
• Lint/cppcheck o.ä. um Konventionen und Schwachstellen zu
finden
• Testframework (Testfälle dokumentieren Funktionalität)
• Zeitkritische Passagen mit Profilern optimieren
• Überprüfung auf Speicherlecks mit profiling Tool
• Logging Mechanismus (wichtig nach Abstürzen)
35/35
19.01.2015
Noch Fragen?
Vielen Dank für Ihre Aufmerksamkeit!

Documents pareils