Übung
Systemprogrammierung 1 - Übung
Der Übungsbetrieb umfasst Tafel- und Rechnerübungen. Jeder Student sollte eine Tafelübung besuchen, zu der eine Anmeldung erforderlich ist. Die Rechnerübungen können ohne vorherige Anmeldung je nach Bedarf besucht werden.
Die Tafelübungen dienen der Vermittlung von Theoriewissen, welches zur Lösung der Übungsaufgaben erforderlich ist. Um an diesem Übungsbetrieb teilnehmen zu können, müssen sich alle Teilnehmer auf Waffel anmelden.
Hinweis: Zu Beginn der Tafelübungen können ein oder auch mehrere Teilnehmer zur Vorstellung ihrer gelösten Übungsaufgabe aufgefordert werden. Nichtanwesenheit oder nicht hinreichende Erklärung der Aufgabe führt hierbei zur Bewertung der Aufgabe mit 0 Punkten.
Zur Information
- Linuxkurs der FSI-Informatik
Übungsfolien
All slides are copyrighted (C) 2011-2022 by Wolfgang Schröder-Preikschat and Jürgen Kleinöder, University of Erlangen-Nürnberg, Germany. Use without prior written permission of the authors is not permitted!- Keine Materialien hinterlegt
- Keine Materialien hinterlegt
Anfertigung, Abgabe und Bewertung der Übungsaufgaben
Soweit in der Aufgabenstellung nicht abweichend beschrieben, sollen alle abgegebenen Programme portabel zur SUSv4/POSIX.1-2008-Systemschnittstelle sein und im Sprachumfang dem C-Standard ISO C11 entsprechen. Alle Programme müssen mit folgenden Compileroptionen übersetzen: Die Abgabe erfolgt über ein Git-Repository und muss vor dem Abgabetermin erfolgen. Dies kann über das Internet geschehen, sodass die Anwesenheit im CIP-Raum nicht notwendig ist. Eine Abgabe per E-Mail oder USB-Stick ist grundsätzlich nicht möglich. Die abgegebenen Aufgaben werden von uns korrigiert und bewertet. Die Ergebnisse der Korrektur sind nach Login im Waffel einsehbar.Aufgaben
Die Übungsaufgaben für das komplette Semester stehen grob fest. Allerdings können sich bis zum Ausgabezeitpunkt noch Details an den Aufgaben ändern.
Die verlinkten Aufgabenstellungen mit einem "Entwurf"-Wasserzeichen im Hintergrund stellen lediglich eine Orientierungshilfe dar. Die endgültigen Aufgabenstellungen werden spätestens am Ausgabetag verlinkt.Auch die Hinweise zur Aufgabe auf dem Aufgabenblatt können Teile der einzuhaltenden Spezifikation enthalten und sind somit explizit als Teil der Aufgabenstellung zu verstehen.
Alle Aufgaben werden den Korrekturhinweisen entsprechend bewertet.
Nr. | Titel | Kurzbeschreibung | Ausgabe | Bearbeitungszeit (Werktage) |
Gruppen | Abzugebende Dateien | Zusatzinfos |
---|---|---|---|---|---|---|---|
0 | epoche | Aufgabe zum Warmwerden | Dienstag, 29.04.2025 | 3 | Nein | epoche.c | |
1 | lilo | Dynamische Speicherallokierung | Dienstag, 29.04.2025 | 6 | Nein | lilo.c | |
2 | wsort | Sortierprogramm ähnlich sort(1) | Dienstag, 06.05.2025 | 7 | Ja | wsort.c | |
3 | clash | Kleine Shell mit Vorder- und Hintergrundprozessen | Dienstag, 13.05.2025 | 12 | Ja | clash.c, plist.c, Makefile | plist API |
4 | mach | Threads, Semaphore | Montag, 02.06.2025 | 10 | Nein | mach.c, queue.c, machfile | |
5 | halde | Einfache dynamische Freispeicherverwaltung | Montag, 23.06.2025 | 10 | Ja | halde.c, Makefile, test.c | |
6 | creeper | Verzeichnisse, Rekursion | Montag, 07.07.2025 | 7 | Ja | Makefile, creeper.c | argumentParser API |
Literaturempfehlungen
Einführung in die Programmiersprache C
- Stephen Kochan: Programming in C. Sams Publishing, 3rd Edition, 2005.
- Karlheinz Zeiner: Programmieren lernen mit C. Carl Hanser, 4. Auflage, 2000.
- Steve Oualline: Practical C Programming. O'Reilly, 1991.
- Peter Darnell, Philip Margolis: C: A Software Engineering Approach. Springer, 1991.
- Brian Kernighan, Dennis Ritchie: The C Programming Language. Prentice Hall, 1988 (in der deutschen Übersetzung 1990 bei Hanser erschienen)
UNIX-Systemprogrammierung
- A. S. Tanenbaum, A. S. Woodhull: Operating Systems: Design And Implementation, Prentice Hall, 1997.
- R. W. Stevens: Advanced Programming in the UNIX Environment. Addison-Wesley, 1992.
Termine
- Tafelübungen: Siehe Waffel-Link unter "Aktuelles" (nach der ersten Vorlesung verfügbar).
- Rechnerübungen: Im Campo unter Menü (links oben) > Studienangebot > Veranstaltungen suchen > "Systemprogrammierung" > Übungen / Rechnerübungen > Parallelgruppen / Termine.
Korrekturhinweise
Die in den Aufgaben beschriebenen Anforderungen müssen durch das Programm erfüllt sein, damit Bonuspunkte gesammelt werden können. Im Folgenden wird erklärt, welche Anforderungen an Abgaben gestellt werden und wofür es Punkte bzw. Punktabzug gibt.
Die folgenden Ausführungen sind dabei als Richtlinien zu verstehen. Sie sind nicht notwendigerweise vollständig. In Ausnahmefällen kann davon abgewichen werden.
Ressourcenfreigabe
Zu Ressourcen gehören insbesondere Arbeitsspeicher und Dateideskriptoren.
Alle angeforderten Ressourcen müssen vor Beendigung des Programms wieder freigegeben werden.
Ausnahme: Wird das Programm aufgrund eines Fehlers beendet, ist keine
Ressourcenfreigabe nötig.
Fehlerbehandlung
Funktionen in C können oft fehlschlagen. Fehler müssen daher adäquat behandelt werden. Unterschiedliche Fehler erfordern unter Umständen unterschiedliche Fehlerbehandlung.
In der Regel erfordern alle Funktionen, die fehlschlagen können, eine Fehlerbehandlung.
Ob und wann eine Funktion fehlschlagen kann, ist in der entsprechenden man
-Page nachzulesen.
Funktionen, die nur bei einer falschen Verwendung durch den Programmierer fehlschlagen können (z.B. sigaction(3p)
),
müssen nicht fehlerbehandelt werden.
Eine gute Fehlerbehandlung sollte folgende Elemente beinhalten:
-
Prüfen, ob und welcher Fehler aufgetreten ist:
Meist durch Auswerten des Rückgabewerts einer Funktion und / oder Auswerten dererrno
.
Achtung: Hiervon gibt es Ausnahmen. -
Ausgabe einer Fehlermeldung:
Meist mitperror(3p)
oderfprintf(3p)
. Die Ausgabe sollte auf der Standard-Fehlerausgabe (stderr
) erfolgen. -
Angemessene Reaktion auf den Fehler im Programm:
Bei Fehlern, die keine sinnvolle Fortsetzung des Programms mehr erlauben, sollte das Programm mitexit(3p)
beendet werden. Andernfalls muss sichergestellt werden, dass das Programm normal weiterlaufen kann und kein unerwartetes Verhalten auftritt.
In Bibliotheksfunktionen ist die Fehlerbehandlung etwas anders. Hier darf weder eine direkte Ausgabe einer Fehlermeldung erfolgen noch das Programm beendet werden. Stattdessen muss der Benutzer der Funktion z.B. durch einen Rückgabewert von dem Fehler informiert werden.
Punktevergabe
Für jede abzugebende Datei ist auf dem Aufgabenblatt die maximal erreichbare Anzahl an Punkten angegeben. Für jeden gemachten Fehler werden Punkte von der Maximalpunktzahl abgezogen. Dazu gehören unter anderem:
- Fehlende oder falsche Funktionalität des Programms
- Fehlende Ressourcenfreigabe
- Mangelnde Fehlerbehandlung
Jede Datei wird mit mindestens 0 Punkten bewertet. Es können also keine Negativpunkte gesammelt werden. Außerdem gelten folgende Regeln:
- Falls nicht anders spezifiziert werden für jedes Auftreten eines Fehlers Punkte abgezogen.
- Auch mehrfacher Punktabzug für dieselbe Art von Fehler an unterschiedlichen Stellen im Programm ist möglich.
- Tritt dieselbe Art von Fehler mehrfach auf, so wird dieser ab dem dritten Auftreten als Folgefehler gewertet und es werden dafür keine Punkte mehr abgezogen.
Für das Arbeiten in Gruppen beliebiger Größe wird außerdem vom Abgabesystem automatisch ein zusätzlicher Bonuspunkt angerechnet.
Gängige Fehler
Im Folgenden werden einige häufig gemachten Fehler aufgeführt. Wir empfehlen das Programm vor der Abgabe auf diese Fehler hin zu überprüfen.
Wenn sich ein Programm nicht übersetzen lässt, werden von der jeweiligen Datei Punkte abgezogen.
Für jeden Auslöser von Übersetzerfehlern werden Punkte abgezogen. Dies betrifft auch vom Übersetzer ausgelöste
Warnungen, da mit -Werror
kompiliert wird.
Fehlerbild | Punktabzug |
---|---|
Auslösen eines Übersetzerfehlers | >= 3 |
Für eine vollständig fehlende Fehlerbehandlung wird meistens nicht mehr als 1 Punkt abgezogen. Für Funktionen, die eine komplexere Fehlerbehandlung erfordern gibt es allerdings Ausnahmen.
Fehlerbild | Punktabzug |
---|---|
Prüfen auf Fehler fehlt | 0,5 |
errno wird zur Fehlerprüfung genutzt, obwohl dies laut Man-Page nicht vorgesehen ist |
0,5 |
Keine Ausgabe einer Fehlermeldung mit perror(3p) oder fprintf(3p)
|
0,5 |
Ausgabe einer Fehlermeldung auf stdout statt auf
stderr |
0,5 |
Keine angemessene Reaktion auf den Fehler im Programm | 0,5 |
Ausgabe einer Fehlermeldung in Bibliotheksfunktionen (z.B. in der halde) | 0,5 |
Beenden des Programms in Bibliotheksfunktionen durch
exit(3p) (z.B. in der halde); abort(3p) ist erlaubt, wenn es die Angabe vorsieht
|
1 |
Fehlerbehandlung ausgewählter Funktionen
Bestimmte Funktionen benötigen eine komplexere Fehlerbehandlung. Einige ausgewählte Funktionen werden hier mit der nötigen Fehlerbehandlung aufgelistet. Auch hierbei ist natürlich die Ausgabe einer Fehlermeldung sowie eine angemessene Reaktion auf den Fehler erforderlich. Die Liste erhebt keinen Anspruch auf Vollständigkeit.
Bei den Kriterien ist der entsprechende Punktabzug mit angegeben. Der maximale Punktabzug für diese Funktionen ist die Summe der angegebenen Abzüge + 1 Punkt für fehlende Ausgabe und Reaktion im Programm.
Nötige Fehlerbehandlung | Punktabzug |
---|---|
strtol(3p) |
|
errno vor dem Aufruf auf 0 setzen |
0,5 |
Prüfen ob endptr auf das Ende der Zeichenkette zeigtDamit wird sichergestellt, dass die Eingabe vollständig gelesen wurde. |
0,5 |
fgets(3p) |
|
Rückgabewert auf NULL prüfen |
0,5 |
Mit feof(3p) bzw. ferror(3p) auf Fehler prüfen |
0,5 |
fgetc(3p) |
|
Rückgabewerte EOF und 0xFF können unterschieden werden |
0,5 |
Prüfen des Rückgabewerts auf EOF |
0,5 |
Mit feof(3p) bzw. ferror(3p) auf Fehler prüfen |
0,5 |
sysconf(3p) |
|
Rückgabewert prüfen | 0,5 |
Falls die angeforderte Information ein (Min-/Max-)Limit ist, passend errno setzen und
prüfen
|
0,5 |
readdir(3p) |
|
Rückgabewert auf NULL prüfen |
0,5 |
errno passend vor jedem Aufruf auf 0 setzen sowie nach Aufruf
prüfen
|
0,5 |
getcwd(3p) |
|
Rückgabewert auf NULL prüfen.
|
0,5 |
Im Fehlerfall errno überprüfen. |
0,5 |
Falls errno gleich ERANGE , ohne Abbruch Fehlergrund beseitigen und erneut
aufrufen |
1 |
getaddrinfo(3p) |
|
Zurückgegebenen Fehlercode prüfen | 0,5 |
Ausgabe des Fehlergrunds. Falls Fehlercode EAI_SYSTEM ist: Ausgabe mit perror(3p) Ansonsten: Ausgabe mit gai_strerror(3p)
|
1 |
Grundsätzlich benötigen alle Funktionen zur Ein- und Ausgabe eine Fehlerbehandlung.
Dies gilt auch für die Ausgabe auf stdout
.
In folgenden Fällen ist allerdings keine Fehlerbehandlung notwendig:
- Die Ausgabe gehört nicht zur Grundfunktionalität des Programms (unwichtige Ausgabe).
- Ausgabe von Fehlermeldungen
- Das Programm würde sich bei einem Ausgabefehler automatisch von selbst beenden (z.B. bei
SIGPIPE
).
Da Ausgaben (auch auf stdout
) gepuffert werden, ist vor Beendigung des Programms ein Aufruf von fflush(3p)
nötig.
Fehlerbild | Punktabzug |
---|---|
free(3p) fehlt |
1 |
close(3p) oder fclose(3p) fehlt |
1 |
Unnötig (deutlich zu) große Puffer | 0,5 |
Fehlerbild | Anmerkung | Punktabzug |
---|---|---|
.PHONY fehlt oder ist unvollständig |
0,5 | |
all (oder Entsprechung) ist nicht erstes Target |
0,5 | |
Abhängigkeit(en) fehlen | pro Target | 0,5 |
Auf der Webseite geforderte Compilerflags fehlen | pro Compileraufruf | 0,5 |
CFLAGS oder CC werden nicht genutzt |
pro Variable | 0,5 |
Verbotene Funktion | Alternative | Punktabzug |
---|---|---|
atoi(3p) |
strtol(3p) |
siehe oben bei strtol(3p) |
Fehlerbild | Punktabzug |
---|---|
Unnötige globale Funktion (static fehlt) |
0,5 |
Die Ausgabe einer Zeichenkette mit printf(3p) ohne Formatstring ist
problematisch.
Stammt die Zeichenkette vom Benutzer, stellt dies eine Sicherheitslücke dar.
Alternative: fprintf(3p) mit "%s" als Format-String.
|
1 |
Zu kleiner Puffer | 1 |
Verlust von benötigter Information durch Casten von Datentypen | 1 |
Falsche Funktionsparameter | 0,5 |
Verwenden der errno , obwohl ihr Wert undefiniert ist.
Erklärung: Da |
0,5 |
Unbegrenzte Speicherallokation durch einen Benutzer möglich (DoS möglich).
Erklärung: Das Lesen von (potentiell) unbegrenzt vielen Zeichen aus einem Stream (z.B.
|
2 |
Auslesen von uninitialisiertem Speicher | 1 |
Zu spätes Freigeben von zuvor angefordertem Speicherplatz | 0,5 |
Sonstige Programmierfehler | 1 |
Fehlerbild | Punktabzug |
---|---|
goto , falls offensichtlich unnötig oder um Schleifen nachzubauen (Sprung nach oben) |
1 |
unnötiges Verwenden von Makros (pro Makro) | 0,5 |
offensichtlich schlechter Code (von Folgefehlern ausgenommen) | 1 |
Muster | Verbesserte Lösung |
---|---|
if (ptr != NULL) free(ptr);
|
free(var); |
if (ptr == 0) |
if (ptr == NULL) |
(*ptr).member |
ptr->member |