Effizientes Memory Debugging in C/C++

Ähnliche Dokumente
Vorkurs C++ Programmierung

Zählen von Objekten einer bestimmten Klasse

Modellierung und Programmierung 1

Objektorientierte Programmierung

Tutorium Rechnerorganisation

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Java Virtual Machine (JVM) Bytecode

Große Übung Praktische Informatik 1

2. Semester, 2. Prüfung, Lösung

Propädeutikum. Dipl.-Inf. Frank Güttler

Prozeß P1 Prozeß P2. Zur Synchronisation stehen den beiden Prozessen binäre Semaphore und die beiden Funktionen

Algorithmen und Datenstrukturen

C A R L V O N O S S I E T Z K Y. Boost C++ Libraries. Johannes Diemke. Department of Computer Science Learning and Cognitive Systems

Grundlagen von Python

Einführung in die Programmierung

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Grundlagen der Programmierung Prof. H. Mössenböck. 10. Klassen

Übungen Programmieren 1 Felix Rohrer. Übungen

Einführung in Javadoc

Testen mit JUnit. Motivation

Valgrind. Speicherleaks und Bugs finden. Frederik Heber. Seminarreihe Technische Numerik. Institut für Numerische Simulation, Universität Bonn

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Arrays von Objekten. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Einführung in die Java- Programmierung

Übung 9 - Lösungsvorschlag

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Operationalisierbare Qualitätskriterien für die Programmierung mit Erfahrungen aus PRÜ1 und PRÜ2

C# im Vergleich zu Java

Java Kurs für Anfänger Einheit 5 Methoden

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

J.5 Die Java Virtual Machine

Prozesse. Stefan Janssen. Alexander Sczyrba

Name: Klausur Programmierkonzepte SS 2011

Objektorientierte Programmierung

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Einführung in die Java- Programmierung

Einführung in die objektorientierte Programmierung mit Java. Klausur am 19. Oktober 2005

5. Tutorium zu Programmieren

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

Klausur in Programmieren

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Multi-Threading. Ralf Abramowitsch Vector Informatik GmbH

Objektorientierte Programmierung. Kapitel 12: Interfaces

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss

Klausur zur Einführung in die objektorientierte Programmierung mit Java

Prinzipien Objektorientierter Programmierung

Wirtschaftsinformatik I

Info-Veranstaltung zur Erstellung von Zertifikaten

SEP 114. Design by Contract

Workshop 6. Einführung in die objektorientierte Programmierung. Teil: Java mit BlueJ

Universität Stuttgart Abteilung Anwendersoftware Steht für Embedded SQL in Java. - Java-Methoden als SQL Stored-Procedures

.NET Code schützen. Projekt.NET. Version 1.0

Einführung in die Programmierung

Alltagsnotizen eines Softwareentwicklers

Einführung in die Programmierung Blockkurs Java

Die Programmiersprache C99: Zusammenfassung

Programmierkurs Java

Zugriff auf die Modul-EEPROMs

Synchronisation in Java. Invisible Web

1. Grundzüge der Objektorientierung 2. Methoden, Unterprogramme und Parameter 3. Datenabstraktion 4. Konstruktoren 5. Vordefinierte Klassen

Fakultät Angewandte Informatik Lehrprofessur für Informatik

Windows Server 2008 für die RADIUS-Authentisierung einrichten

OO Softwareentwicklung

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Hochschule Darmstadt Fachbereich Informatik

Client-Server-Beziehungen

Graphic Coding. Klausur. 9. Februar Kurs A

Programmieren für Ingenieure Sommer Ein Rechner. Rechner sind überall. Gerät, das mittels programmierbarer Rechenvorschriften Daten verarbeitet.

Objektorientierte Programmierung mit C++ Vector und List

0. Einführung. C und C++ (CPP)

C/C++-Programmierung

Wie halte ich Ordnung auf meiner Festplatte?

Universität Karlsruhe (TH)

Software Engineering Klassendiagramme Assoziationen

1. Übung zu "Numerik partieller Differentialgleichungen"

Studentische Lösung zum Übungsblatt Nr. 7

Vererbung & Schnittstellen in C#

Lehrstuhl für Datenverarbeitung. Technische Universität München. Grundkurs C++ Debugging

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Tagesprogramm

Debugging und Speicherfehler. Seminar Effiziente Programmierung Kadir Duman

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 18

Anwenderleitfaden Citrix. Stand Februar 2008

Gliederung Grundlagen Schlüsselworte try-catch Fehlerobjekte Fehlerklassen Schlüsselwort finally Schlüsselwort throws selbst erstellte Exceptions

Arrays Fortgeschrittene Verwendung

Innere Klassen in Java

Deklarationen in C. Prof. Dr. Margarita Esponda

Reporting Services und SharePoint 2010 Teil 1

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java

Java Einführung Abstrakte Klassen und Interfaces

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf

AUTOMATISCHE -ARCHIVIERUNG. 10/07/28 BMD Systemhaus GmbH, Steyr Vervielfältigung bedarf der ausdrücklichen Genehmigung durch BMD!

8 Zugriffstypen ( Zeiger )

Verwendung des IDS Backup Systems unter Windows 2000

Swisscom TV Medien Assistent

Java Einführung Collections

Software Entwicklung 1

Domänenmodell: Fadenkommunikation und -synchronisation

DOKUMENTATION VOGELZUCHT 2015 PLUS

Prof. Dr. Uwe Schmidt. 21. August Aufgaben zur Klausur Objektorientierte Programmierung im SS 2007 (IA 252)

Transkript:

Effizientes Memory Debugging in C/C++ Adam Szalkowski Embedded Computing Conference 2014

Ursachen/ Symptome Debugging Tools

Ursachen / Symptome Was habe ich falsch gemacht? Was kann denn passieren im schlimmsten Fall? Aber mein Code funktioniert doch

1. Memory Leaks Allozierter Speicher, der nicht wieder freigegeben wird Nicht-virtueller Destruktor Freigabe durch Exception Handling übersprungen Symptome: Systemspeicher läuft voll

1. Memory Leaks Allozierter Speicher, der nicht wieder freigegeben wird Nicht-virtueller Destruktor Freigabe durch Exception Handling übersprungen Symptome: Systemspeicher läuft voll void MemoryLeak() { int* array = new int[4]; if (condition) { throw Exception(); } delete[] array; }

2. Falsche Speicheroperationen Unpassendes free/delete/delete[] Unpassendes free/delete/delete[] nach malloc/new/new[] delete von lokalen/globalen Objekten Mehrfaches delete Gefahren: Programmabbruch Destruktor wird nicht ausgeführt Je nach Implementierung können die Heap Datenstrukturen inkonsistent werden

2. Falsche Speicheroperationen Unpassendes free/delete/delete[] Unpassendes free/delete/delete[] nach malloc/new/new[] delete von lokalen/globalen Objekten Mehrfaches delete Gefahren: Programmabbruch void WrongDelete() { int* array = new int[4]; delete array; delete array; } Destruktor wird nicht ausgeführt Je nach Implementierung können die Heap Datenstrukturen inkonsistent werden

3. Nicht initialisierte Variable Variable, die vor der Verwendung nicht initialisiert wurden Allokation auf Heap oder Stack Ignorieren von Compilerwarnung Symptome: Verhalten abhängig von Compileroptimierungen Zufällige Initialisierung Kann bei jedem Funktionsaufruf verschieden sein

3. Nicht initialisierte Variable Variable, die vor der Verwendung nicht initialisiert wurden Allokation auf Heap oder Stack Ignorieren von Compilerwarnung Symptome: Verhalten abhängig von Compileroptimierungen Zufällige Initialisierung void UninitializedLocal() { int array[4]; if (array[2] > 0) { } else { } } Kann bei jedem Funktionsaufruf verschieden sein

4. Ungültige Referenzen Zeiger auf Speicherorte, die eigentlich nicht mehr gültig sind Freigegebener Speicher Lokale Variable ausserhalb des Scope (z.b. nach return) Gefahren: Andere Werte können überschrieben werden Wert kann sich zu jedem Zeitpunkt ändern Abhängig von Compileroptimierungen

4. Ungültige Referenzen Zeiger auf Speicherorte, die eigentlich nicht mehr gültig sind Freigegebener Speicher Lokale Variable ausserhalb des Scope (z.b. nach return) Gefahren: void OutsideOfScope() { int* array; if (array[2] > 0) { int scoped_array[4]; array = &scoped_array; } int x,y; Andere Werte können überschrieben werden array[1] = 1; Wert kann sich } zu jedem Zeitpunkt ändern Abhängig von Compileroptimierungen

5. Index-Überlauf (OOB) Zugriff auf Elemente ausserhalb eines allozierten Speicherbereichs Off-by-one Fehler Fehlende Terminierung von Strings (z.b. nach strncpy) Gefahren: Lokale oder globale Variable können überschrieben werden Heap Datenstrukturen können überschrieben werden Potentielle Sicherheitslücken!

5. Index-Überlauf (OOB) Zugriff auf Elemente ausserhalb eines allozierten Speicherbereichs Off-by-one Fehler Fehlende Terminierung von Strings (z.b. nach strncpy) Gefahren: void ArrayLocalOOB() { int array[4]; int scalar = 3; Lokale oder globale Variable können überschrieben werden } Heap Datenstrukturen können überschrieben werden Potentielle Sicherheitslücken! for(int i=1; i <= 4; ++i) { array[i] = 0; }

6. Strict Aliasing Zwei Pointer verschiedenen Typs dürfen nicht auf dasselbe Objekt zeigen Seit C89/90 bzw C++98 Teil des Standards Erlaubt viele Compileroptimierungen Compiler darf Operationen umsortieren Compiler darf annehmen, dass sich Werte von Variablen nicht ändern Gefahren: Unerwartete Ergebnisse

6. Strict Aliasing Zwei Pointer verschiedenen Typs dürfen nicht auf dasselbe Objekt zeigen Seit C89/90 bzw C++98 Teil des Standards Erlaubt viele Compileroptimierungen Compiler darf Operationen umsortieren Compiler value darf annehmen, = 1; dass sich Werte von Variablen nicht ändern Gefahren: void StrictAliasing() { int value; set_values(value, reinterpret_cast<short*>(&value)); } static void set_values( int& value, short* value2) { } *value2 = 2; value = value - *value2; Unerwartete Ergebnisse

7. Data Race Unsynchronisierte Speicherzugriffe zwischen mehreren Threads Fehlende Synchronisierung durch Mutexe, Semaphoren & co Nicht-atomare Operationen Gefahren: Unerwartete Ergebnisse Fehlende Synchronisierung

7. Data Race Unsynchronisierte Speicherzugriffe zwischen mehreren Threads Fehlende Synchronisierung durch Mutexe, Semaphoren & co Nicht-atomare Operationen Gefahren: static volatile int value; void* thread_proc(void* param) { for(int i=0; i<1000000; ++i) { value += 1; } return 0; } Unerwartete Ergebnisse Fehlende Synchronisierung

Debugging Tools Welche Fehler kann/muss man statisch detektieren? Wie kann man fehlerhafte Speicherzugriffe automatisch detektieren? Was kann ich tun um Fehler zu vermeiden?

With a little help from my compiler Memory Leaks Nicht initialisierte Variable Statische Analyse und Laufzeittests Voraussetzungen: -Wall -O1 (besser -O2) -Wstrict-aliasing=2 -fstack-protector-all Ungültige Referenzen Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

Statische Analysen Clang Static Analyzer CppCheck Oink Cqual++ Splint cccc Klocwork Insight Gimpel Coverity PC-Lint PVS-Studio... Memory Leaks Nicht initialisierte Variable Ungültige Referenzen Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

GDB Memory Leaks Watchpoints (gdb) print &(x->a) (gdb) watch *$1 (gdb) continue Conditional Breakpoints (gdb) break main.cpp:20 (gdb) cond 1 (i == 3) Nicht initialisierte Variable Ungültige Referenzen Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

valgrind Memory Leaks Framework zur automatischen dynamischen Analyse von Programmen Unterstützt viele Architekturen Nur Linux (und Mac OSX) Nicht initialisierte Variable Ungültige Referenzen Memcheck SGCheck Helgrind Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

Dr. Memory Memory Leaks Nicht initialisierte Variable Ungültige Referenzen Windows und Linux Nur Intel x86 (32bit) Features und Performance ähnlich zu memcheck Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

Address/Thread Sanitizer GCC >= 3.8, clang >= 3.2 Memory Leaks Nicht initialisierte Variable Address Sanitizer: -fsanitize=address Thread Sanitizer: -fsanitize=thread Findet Data races und new/delete races Ungültige Referenzen Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

Vermeiden ist billiger als Fehlersuche Vermeiden von Pointern/new/delete std::shared_ptr, std::unique_ptr std::vector, std::string, std::array in-class initialization of non-static members class C { int a = 1; }; Synchronisation und atomare Operationen std::atomic std::lock_guard, std::call_once, std::future Memory Leaks Nicht initialisierte Variable Ungültige Referenzen Falsche Speicheroperationen Index-Überlauf Strict Aliasing Data Race

Ursachen/ Symptome Debugging Tools