Systemnahe Programmierung in C/C++ - -

Transcription

Systemnahe Programmierung in C/C++ - -
Systemnahe Programmierung in C/C++
– Modularisierung, Makefiles und Debugging –
Knut Stolze
stolze@informatik.uni-jena.de
Lehrstuhl für Datenbanken und Informationssysteme
Fakultät für Mathematik und Informatik
2006–11–08
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
1 / 42
Agenda
1
Modularisierung
Module
Bibliotheken
2
Makefiles
3
Debugging & Tracing
Debugging
Tracing
Profiling
Speicherverwaltung
4
Aufgaben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
2 / 42
Outline
1
Modularisierung
Module
Bibliotheken
2
Makefiles
3
Debugging & Tracing
Debugging
Tracing
Profiling
Speicherverwaltung
4
Aufgaben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
3 / 42
Modularisierung
1
Dateiintern: Aufteilung von Funktionen in verschiedene
Übersetzungseinheiten
⇒ Nicht weiter diskutiert
2
3
Objektebene: Module als Mechanismus ähnlich zum
Klassenkonzept in OO-Programmiersprachen
Packaging: Implementierung von Bibliotheken
⇒ Bereits bekannt
4
Architekturebene: Prozesse vs. Threads
⇒ Nächste Woche
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
4 / 42
Module
Einzige höhere Abstraktion in C (Klassen in Java/C++)
⇒ Reichlich Gebrauch davon machen
Modul definiert Struktur
Alle Funktionen erhalten Zeiger auf Stuktur als ersten Parameter
Header:
#if !defined(__MODULE_H__)
#define __MODULE_H__
struct mod_data;
mod_data* mod_open(char *init, ...);
int mod_action(mod_data *dat, int arg1,
char *arg2, ...);
int mod_close(mod_data *dat);
#endif
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
5 / 42
Module (cont.)
#include "module.h"
struct mod_data {
long internal_state;
...
}
/* private */
int function(int arg, ...) {
...
}
/* public */
mod_data* mod_open(char *init, ...) {
...
}
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
6 / 42
Module – Tipps
Schnittstelle sauber entwerfen
Schnittstelle im Header-File dokumentieren
Schnittstelle auch auf Testbarkeit hin gestalten
Header gegen Mehrfachinklusion schützen
APIs symmetrisch gestalten (open – close)
Defensiv programmieren
Funktion bei Fehlern so schnell wie möglich beenden
Bei Fehler definierten Zustand hinterlassen
Argumente von extern aufgerufenen Funktionen immer validieren
Globale Variablen mit static schützen
Kein Zugriff auf Variablen anderer Module (mittels external)
Accessor-Funktionen einsetzen
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
7 / 42
Bibliotheken
1
Zur Compile-Zeit hinzuge„link“t
⇒ Bereits bekannt
2
Dynamisch zur Laufzeit geladen
Funktionen: dlopen, dlclose und dlsym
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
8 / 42
Dynamische Verwendung von Bibliotheken
void *dlopen(const char *filename, int flag)
Lädt angegebene Bibliothek
Gibt DLL-Handle zurück
Verschiedene Optionen zur Kontrolle des Ladevorgangs
int dlclose(void *handle)
Schliesst geladene Bibliothek
Gibt Resourcen frei
void *dlsym(void *handle, const char *symbol)
Gibt Addresse des angegebenen Symbols
⇒ Zeiger auf Variable oder Funktionszeiger
Funktionsnamen in C eindeutig ⇒ Symbol = Funktionsname
C++ hat Name Mangeling
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
9 / 42
Dynamische Verwendung von Bibliotheken
void *dlopen(const char *filename, int flag)
Lädt angegebene Bibliothek
Gibt DLL-Handle zurück
Verschiedene Optionen zur Kontrolle des Ladevorgangs
int dlclose(void *handle)
Schliesst geladene Bibliothek
Gibt Resourcen frei
void *dlsym(void *handle, const char *symbol)
Gibt Addresse des angegebenen Symbols
⇒ Zeiger auf Variable oder Funktionszeiger
Funktionsnamen in C eindeutig ⇒ Symbol = Funktionsname
C++ hat Name Mangeling
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
9 / 42
Dynamische Verwendung von Bibliotheken
void *dlopen(const char *filename, int flag)
Lädt angegebene Bibliothek
Gibt DLL-Handle zurück
Verschiedene Optionen zur Kontrolle des Ladevorgangs
int dlclose(void *handle)
Schliesst geladene Bibliothek
Gibt Resourcen frei
void *dlsym(void *handle, const char *symbol)
Gibt Addresse des angegebenen Symbols
⇒ Zeiger auf Variable oder Funktionszeiger
Funktionsnamen in C eindeutig ⇒ Symbol = Funktionsname
C++ hat Name Mangeling
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
9 / 42
Outline
1
Modularisierung
Module
Bibliotheken
2
Makefiles
3
Debugging & Tracing
Debugging
Tracing
Profiling
Speicherverwaltung
4
Aufgaben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
10 / 42
Makefiles
Besteht aus Menge von Regeln
Steuert Übersetzung von Programmen
Ziel: Quelle Quelle ...
Shellkommando
Shellkommando
...
Ziel ist Name einer Datei
Gibt an, welche Datei erzeugt wird
Falls eine Quelle neuer als Ziel, werden Kommandos ausgeführt
Quelle kann in anderen Regeln andere Vorraussetzungen haben
Aktualität und Existenz der Quellen wird rekursiv behandelt
Shellkommandos müssen Ziel aus Quellen erzeugen
Müssen durch <TAB> eingeleitet werden
Voranstellung:
’-’ ignoriere Fehler
’@’ Kommando selbst nicht ausgeben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
11 / 42
Makefile – Beispiel
prog: mod1.o mod2.o mod3.o
gcc mod1.o mod2.o mod3.o -lm \
-lglib -o prog
mod1.o: mod1.c
gcc -Wall -O2 -c mod1.c
mod2.o: mod2.c
gcc -Wall -O2 -c mod2.c
mod3.o: mod3.c
gcc -Wall -O2 -c mod3.c
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
12 / 42
Variablen & Funktionen
Wiederholter Text kann durch Variablen ersetzt werden
Variablen als Listen interpretiert
Funktionen zur Manipulation
SOURCES := mod1.c mod2.c mod3.c
OBJECTS := $(patsubst .c, .o, $(SOURCES))
CC := gcc
prog: $(OBJECTS)
$(CC) $(OBJECTS) -lglib -o prog
Spezielle Variablen:
$@ Ziel
$< Erste Quelle
$∧ Alle Quellen (über mehrere Regeln)
$? Quellen, die aktueller als Ziel sind
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
13 / 42
Spezielle Regeln
Regeln mit Mustern
Platzhalter % definiert Regelmengen
Kommandosequenzen können zusammengefasst und 1x definiert
werden
Verwendung wie Variablen
Mit define ... endef definiert
Regeln für häufig vorkommende Anwendungsfalle bereits in make
eingebaut
Siehe info make
Möglichst wenig verwenden weil implizit
Phony Targets
Ziele, für die nie eine gleichnamige Datei erzeugt wird
clean:
rm -f *~ *.o core prog
.PHONY: clean
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
14 / 42
Beispiel
SOURCES := mod1.c mod2.c mod3.c
OBJECTS := $(patsubst .c, .o, $(SOURCES))
CC := gcc
CFLAGS := -Wall -O2
define link-source
$(CC) $(OBJECTS) -lglib -o prog
endef
define compile-source
$(CC) $(CFLAGS) -c $< -o $@
endef
prog: $(OBJECTS)
$(link-source)
%.o: %.c
$(compile-source)
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
15 / 42
Abhängigkeiten
Abhängigkeiten können automatisch generiert werden
Von C/C++ Quellcode
Kommando makedepend
Teil von X11
Kompileroption
-M für gcc
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
16 / 42
Strukturierung von Makefiles
Abhängigkeiten oft in separate Dateien ausgelagert
Z. B. .dep oder .make.dep
Plattformabhängige Einstellungen separiert
Z. B. unterschiedliche Compiler auf verschiedenen Plattformen
Komponentenspezifische Makefiles
include ../makefile.aix
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
17 / 42
Outline
1
Modularisierung
Module
Bibliotheken
2
Makefiles
3
Debugging & Tracing
Debugging
Tracing
Profiling
Speicherverwaltung
4
Aufgaben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
18 / 42
Debugging
Schrittweises Nachvollziehen der Logik eines Programms und
seiner Funktionen
Direkter Zugriff auf und Modifikation von Variablen und
Speicherinhalt
Programm muss vor dem Debugging nicht übersetzt oder
geändert werden
Debug-Informationen jedoch notwendig
Compiler-Option -g
Übersetzung mit Optimierung beeinflusst Abbildung zwischen
Quelltext und Maschinencode
Nicht Option -Ox verwenden
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
19 / 42
Debugging
Schrittweises Nachvollziehen der Logik eines Programms und
seiner Funktionen
Direkter Zugriff auf und Modifikation von Variablen und
Speicherinhalt
Programm muss vor dem Debugging nicht übersetzt oder
geändert werden
Debug-Informationen jedoch notwendig
Compiler-Option -g
Übersetzung mit Optimierung beeinflusst Abbildung zwischen
Quelltext und Maschinencode
Nicht Option -Ox verwenden
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
19 / 42
Debugging
Schrittweises Nachvollziehen der Logik eines Programms und
seiner Funktionen
Direkter Zugriff auf und Modifikation von Variablen und
Speicherinhalt
Programm muss vor dem Debugging nicht übersetzt oder
geändert werden
Debug-Informationen jedoch notwendig
Compiler-Option -g
Übersetzung mit Optimierung beeinflusst Abbildung zwischen
Quelltext und Maschinencode
Nicht Option -Ox verwenden
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
19 / 42
Debugger
1
Bearbeiten von bereits laufenden Programmen möglich
⇒ Debugger verbindet sich zu existierenden Prozess
Option „attach“ (häufig -a)
2
Analysieren von core Dateien
Eine Art Log bei Programmabstürzes
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
20 / 42
Core Dumps
Datei, die bei bestimmten Signalen geschrieben wird
SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGBUS,
SIGSYS, SIGTRAP, SIGXCPU, SIGXFSZ
Image des Speichers eines Prozesses
Heap + Stack
Implizit Aufrufreihenfolge von Funktionen bekannt
Größe von core Dateien kann limitiert werden
Funktion getrlimit
Kommando ulimit
Core wird nicht geschrieben, wenn
Keine Rechte im Zielverzeichnis
core existiert bereits und ist read-only
Größe auf 0 Bytes beschränkt
...
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
21 / 42
Typische Debuggerfunktionalität
Run
⇒ Starte Programm
evtl. mit zusätzlichen Kommandozeilenoptionen
Breakpoint setzen
⇒ Programmausführung wird beim Erreichen unterbrochen
Debugger sendet Signal an Prozess
Next
⇒ Führe einen Schritt in Funktion aus
Step
⇒ Steige in aufgerufene Funktion hinab
Wenn nicht möglich, führe einen Schritt in aktuelle Funktion aus
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
22 / 42
Typische Debuggerfunktionalität (cont.)
Continue
⇒ Setzt Programmausführung bis zum nächsten Breakpoint fort
Keine Schrittweise Abarbeitung
Restart
⇒ Starte Programm komplett neu
Nötig, wenn Kontrollfluss bereits nach gewünschtem Ereignis ist
Backtrace
⇒ Gibt aktuellen Aufruf-Stack aus
Print
⇒ Variablen/Datenstrukturen anzeigen (global und lokal)
Set
⇒ Setze Wert einer Variable oder Speicherbereichs
...
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
23 / 42
Debugger – Beispiele
Kommandozeilen-Debugger gdb
$ gdb <programm-name>
Unerlässlich: help-Befehl
Sehr hilfreich wenn keine graphische Oberfläche verfügbar
Grafische Debugger
Meist besser und übersichtlicher
Quelltext, Variablen, Aufruf-Stack, . . . werden parallel angezeigt
ddd GNU Debugger, basiert auf gdb
xldb IBM AIX Debugger (bereits in die Jahre gekommen)
idebug AIX Debugger
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
24 / 42
Debugger – Beispiele
Kommandozeilen-Debugger gdb
$ gdb <programm-name>
Unerlässlich: help-Befehl
Sehr hilfreich wenn keine graphische Oberfläche verfügbar
Grafische Debugger
Meist besser und übersichtlicher
Quelltext, Variablen, Aufruf-Stack, . . . werden parallel angezeigt
ddd GNU Debugger, basiert auf gdb
xldb IBM AIX Debugger (bereits in die Jahre gekommen)
idebug AIX Debugger
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
24 / 42
ddd
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
25 / 42
Internas
1
Debugger startet Programm
Debugger & Programm sind ein Prozess
⇒ Debugger kann auf Speicher und Strukturen des Programms
zugreifen
2
Debugger verbindet sich zu bereits laufendem Prozess
Debugger & Programm sind verschiedene Prozesse
Betriebssystem trennt klar beide Adressräume
⇒ Spezielle Systemfunktion erlaubt Zugriff auf Speicher anderer
Prozesse
Funktion nicht selber nutzen, da sehr schwierig zu handhaben und
risikobehaftet
Besondere Rechte notwendig
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
26 / 42
Internas
1
Debugger startet Programm
Debugger & Programm sind ein Prozess
⇒ Debugger kann auf Speicher und Strukturen des Programms
zugreifen
2
Debugger verbindet sich zu bereits laufendem Prozess
Debugger & Programm sind verschiedene Prozesse
Betriebssystem trennt klar beide Adressräume
⇒ Spezielle Systemfunktion erlaubt Zugriff auf Speicher anderer
Prozesse
Funktion nicht selber nutzen, da sehr schwierig zu handhaben und
risikobehaftet
Besondere Rechte notwendig
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
26 / 42
Tracing
Programme werden nicht mit Debug-Informationen ausgeliefert.
Optimierung
Bessere Laufzeit
Besseres Cache-Verhalten
Starten/Attachen eines Debuggers nicht möglich
⇒ Nachvollziehen des Programmablaufs mit anderen Mitteln
Instrumentieren des Codes
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
27 / 42
Tracing
Programme werden nicht mit Debug-Informationen ausgeliefert.
Optimierung
Bessere Laufzeit
Besseres Cache-Verhalten
Starten/Attachen eines Debuggers nicht möglich
⇒ Nachvollziehen des Programmablaufs mit anderen Mitteln
Instrumentieren des Codes
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
27 / 42
Tracing (cont.)
Dedizierte Kompontente
Sammelt Trace-Informationen bei Bedarf
Im fertigen Produkt mit vorhanden
Informationen
Eintritt & Verlassen von Funktionen
Daten an ausgewählten Zwischenpunkten
Informationen beschränkt!
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
28 / 42
Tracing (cont.)
Dedizierte Kompontente
Sammelt Trace-Informationen bei Bedarf
Im fertigen Produkt mit vorhanden
Informationen
Eintritt & Verlassen von Funktionen
Daten an ausgewählten Zwischenpunkten
Informationen beschränkt!
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
28 / 42
Tracing (cont.)
Dedizierte Kompontente
Sammelt Trace-Informationen bei Bedarf
Im fertigen Produkt mit vorhanden
Informationen
Eintritt & Verlassen von Funktionen
Daten an ausgewählten Zwischenpunkten
Informationen beschränkt!
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
28 / 42
Beispiel „System J“
Macros:
DBJ_TRACE_ENTRY()
DBJ_TRACE_EXIT()
DBJ_TRACE_ACTIVE()
DBJ_TRACE_DATA1(tracePoint,
length1, data1)
DBJ_TRACE_DATA2(tracePoint,
length1, data1, length2, data2)
DBJ_TRACE_DATA3(tracePoint,
length1, data1, length2, data2,
length3, data3)
DBJ_TRACE_NUMBER(tracePoint, str, val)
DBJ_TRACE_STRING(tracePoint, str)
Einfache Prüfung zum An-/Abschalten des Tracings
if (dbj_trace_on) { ...}
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
29 / 42
Profiling
Profiling: Wo verbraucht ein Programm seine Zeit?
1
Kompilieren und Linken mit eingeschalteten Profiling
GCC-Option -pg
2
Ausführen des Programms, um Profiling-Daten zu sammeln
Produziert Datei gmon.out beim Programmende
3
Analysieren der Daten
4
Andere Programme und Mechanismen
Programm gprof
Valgrind + Visualisierung
http://valgrind.org
http://kcachegrind.sourceforge.net/
...
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
30 / 42
gprof – Beispiel
gcc profiling.c -pg
./a.out
gprof -b -Q a.out
%
cumulative
time
seconds
0.00
0.00
0.00
0.00
0.00
0.00
0.00
0.00
Knut Stolze (DBIS)
self
seconds
0.00
0.00
0.00
0.00
calls
1
1
1
1
self
Ts/call
0.00
0.00
0.00
0.00
total
Ts/call
0.00
0.00
0.00
0.00
C/C++ Programmierung
name
fct1
fct1_1
fct1_2
fct2
2006–11–08
31 / 42
Code Coverage Testing
Überprüfen, welche Anweisungen und Pfade ausgeführt werden
White-Box Testing
Tools
gcov
xSuds
Purify
JCover
...
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
32 / 42
gcov
Arbeiten mit gcc zusammen
1
gcc -fprofile-arcs -ftest-coverage profiling.c
2
./a.out
⇒ Instrumentiert und übersetzt Programm
⇒ Sammelt Profiling-Informationen
3
gcov -a profiling.c
⇒ Formatiert Profiling-Informationen
4
cat profiling.c.gcov
-:
1:
1:
1:
1:
...
-:
1:
1:
1:
1:
1:
-:
Knut Stolze (DBIS)
3:void fct1_1()
4:{
5:
printf("Function 1-1\n");
5-block 0
6:}
25:int main()
26:{
27:
fct1();
27-block 0
28:
fct2();
29:
return 0;
30:}
C/C++ Programmierung
2006–11–08
33 / 42
Speicherverwaltung
Nachvollziehen, welche Speicherblöcke allokiert wurden?
Wo angefordert?
Welche Größe?
⇒ Keine Unterstützung vom Betriebssystem
⇒ Muss Anwendung selbst abdecken
Entsprechende Bibliotheken einsetzen
Eigene Funktionen schreiben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
34 / 42
Speicherverwaltung
Nachvollziehen, welche Speicherblöcke allokiert wurden?
Wo angefordert?
Welche Größe?
⇒ Keine Unterstützung vom Betriebssystem
⇒ Muss Anwendung selbst abdecken
Entsprechende Bibliotheken einsetzen
Eigene Funktionen schreiben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
34 / 42
Speicherverwaltung
Nachvollziehen, welche Speicherblöcke allokiert wurden?
Wo angefordert?
Welche Größe?
⇒ Keine Unterstützung vom Betriebssystem
⇒ Muss Anwendung selbst abdecken
Entsprechende Bibliotheken einsetzen
Eigene Funktionen schreiben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
34 / 42
Systemfunktionen abfangen
Bibliothek X mit Funktionen malloc, free etc.
Umgebungsvariable LD_PRELOAD lädt X
Symbole im Programm werden gegen X aufgelöst ⇒ malloc,
free etc.
Alle weiteren Symbole gegen libc aufgelöst
Accounting in eigener Implementierung
Funktionen weitergereicht
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
35 / 42
Systemfunktionen abfangen
Bibliothek X mit Funktionen malloc, free etc.
Umgebungsvariable LD_PRELOAD lädt X
Symbole im Programm werden gegen X aufgelöst ⇒ malloc,
free etc.
Alle weiteren Symbole gegen libc aufgelöst
Accounting in eigener Implementierung
Funktionen weitergereicht
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
35 / 42
Systemfunktionen abfangen
Bibliothek X mit Funktionen malloc, free etc.
Umgebungsvariable LD_PRELOAD lädt X
Symbole im Programm werden gegen X aufgelöst ⇒ malloc,
free etc.
Alle weiteren Symbole gegen libc aufgelöst
Accounting in eigener Implementierung
Funktionen weitergereicht
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
35 / 42
Systemfunktionen abfangen
Bibliothek X mit Funktionen malloc, free etc.
Umgebungsvariable LD_PRELOAD lädt X
Symbole im Programm werden gegen X aufgelöst ⇒ malloc,
free etc.
Alle weiteren Symbole gegen libc aufgelöst
Accounting in eigener Implementierung
Funktionen weitergereicht
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
35 / 42
Outline
1
Modularisierung
Module
Bibliotheken
2
Makefiles
3
Debugging & Tracing
Debugging
Tracing
Profiling
Speicherverwaltung
4
Aufgaben
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
36 / 42
Allgemeine Hinweise
Achten Sie auf ordnungsgemäße Fehlerbehandlung in allen Fällen.
Alle Resourcen, die eine Programm oder eine Bibliothek verwendet,
sind explizit freizugeben. Es soll/darf sich nicht auf das Betriebssystem
verlassen werden. (In Bibliotheken kann man das sowieso nicht, und in
allen anderen Fällen ist es einfach guter Stil.)
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
37 / 42
Aufgabe 1 – Makefiles
Schreiben Sie ein Makefile, welches auf alle nachfolgenden
Aufgaben 2-5 zugeschnitten ist und die jeweiligen Dateien übersetzt,
„link“t, und ausführt. Zusätzlich ist eine Möglichkeit zum Aufräumen
bzw. Löschen aller Dateien, die keine Quelldateien sind,
bereitzustellen.
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
38 / 42
Aufgabe 2 – Modularisierung
Implementieren Sie ein Modul (siehe Slide 5), welches Strings in einer
Struktur verwaltet. Die Struktur hat den String bzw. eine Kopie davon
selbständig zu verwalten, d. h. einschliesslich der nötigen
Speicherallokationen. Zusätzlich sind folgende Funktionen
bereitzustellen:
a) Kreieren eines neuen, leeren Strings (Allokieren und Intialisieren),
b) Zerstören und Freigeben des Strings und der Struktur,
c) Anhängen eines C-Strings (Typ char *),
d) Konkatenieren von zwei Strings, die in besagten Strukturen
verwaltet werden,
e) Ermitteln der aktuellen Länge des Strings,
f) Ermitteln der Länge des aktuell allokierten Puffers.
Wir nehmen an, dass keine Multibyte-Zeichensätze verwendet werden
und damit keine Konvertierungen zwischen Zeichensätzen nötig sind.
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
39 / 42
Aufgabe 3 – Profiling/Coverage
Schreiben Sie ein Programm, dass die verschiedenen Funktionen des
Moduls aus Aufgabe 2 verwendet und testet. Die Funktionen aus
Aufgabe 2 können entweder direkt (also .o-Datei) hinzuge„linkt“ oder
als Bibliothek (shared library) eingebunden werden.
a) Nutzen Sie Profiling, um zu überprüfen, welche Funktionen die
meiste Zeit benötigen. (Eventuell benötigen Sie eine Reihe von
Aufrufen, um aussagefähige Zahlen zu erhalten.)
b) Verwenden Sie gcov um die Code Coverage des Moduls durch Ihr
Testprogramm zu ermitteln.
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
40 / 42
Aufgabe 4 – Speicherauditing
Implementieren Sie eigene Versionen aller dynamischen C
Speicherfunktionen, die nachvollziehen, wann ein Speicherblock
allokiert (in welcher Größe), und wann er wieder freigegeben wurde.
Bauen Sie eine Bibliothek (shared library) in der die Funktionen
aufgenommen werden.
Verwenden Sie diese Bibliothek, um die Nutzung des Speichers
(Heaps) durch das Testprogramm von Aufgabe 3 nachzuvollziehen.
Dafür ist gegebenenfalls der Quelltext von Aufgabe 2 und 3
anzupassen, damit die neuen Funktionen verwendet werden.
Das Nachverfolgen der Speicheroperationen soll mit einer
Umgebungsvariable an- bzw. abgeschaltet werden können.
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
41 / 42
Aufgabe 5 – Dynamische Bibliotheken
Implementieren Sie ein Programm, welches die Bibliothek aus
Aufgabe 4 dynamisch lädt, und die 5 Speicherfunktionen (welche sind
das?) aus der Bibliothek ermittelt und Funktionszeigern zuweist.
In 2-3 Beispielen sind diese Funktionszeiger bei Speicheroperationen
zu verwenden.
Zwischendurch ist die Bibliothek wieder zu entladen, und die regulären
Speicherfunktionen (malloc, realloc etc.) sind zu verwenden –
selbstverständlich über die Funktionszeiger.
Knut Stolze (DBIS)
C/C++ Programmierung
2006–11–08
42 / 42