Kalender
| Datum | Thema | Material |
|---|---|---|
| 2019-10-25 | IPC, Netzwerkkommunikation als Client, Sockets | caseconv.c |
| 2019-10-31 | Übung entfällt | |
| 2019-11-08 | Übung entfällt | |
| 2019-11-15 | Netzwerkkommunikation als Server, Signale | troll.tar.gz |
| 2019-11-22 | Besprechung snail | |
| 2019-11-29 | Signale und Nebenläufigkeit, Vorbesprechung rush | waiter.c |
| 2019-12-06 | Besprechung sister | |
| 2019-12-13 | Synchronisation bei Nebenläufigkeit, Vorbesprechung jbuffer | |
| 2019-12-20 | Weihnachtshacking ^^ | exploit.c |
Tipps zu den Aufgaben
sister
- listen Socket vor der Anfragenbehandlung schließen Falls in der Anfragenbehandlung irgendwelche Sicherheitslücken bestehen, will man nicht dass der Angreifer mit anderen Clients reden kann.
-
getaddrinfo(3) für
struct sockaddrist optional Kann man machen wenn man will, ist für unsere Zwecke aber Overkill. Stattdessen kann man auch einfach einstruct sockaddr_in6verwenden. Dann aber dashtonsnicht vergessen. -
Blockierende Systemaufrufe gegebenenfalls neustarten
Wenn während einem blockierenden Systemaufruf wie
accept(2) ein Signal
ankommt wird der Aufruf unterbrochen und setzt die
errnoaufEINTR. Dann muss der Systemaufruf neugestartet werden.
Checkliste für Abgaben
- Fehlerbehandlung nicht vergessen :) In den manpages steht, welche Fehler während den jeweiligen Funktionen auftreten können.
-
Sichtbarkeit einschränken
Soweit möglich Funktionen und Variablen als
staticdeklarieren. -
Bei Funktionen ohne Argumente, die Argumentliste mit
voidkennzeichen Ansonsten könnte man die Funktion mit einer beliebigen Anzahl an Parametern aufrufen. - Auch Randfälle testen Das Programm ist nicht korrekt, wenn es nur für "richtige" Eingaben das Richtige tut.
- Auf einem CIP-Rechner kompilieren Unterschiedliche Compiler(-versionen) werfen gerne unterschiedliche Warnungen. Die CIP-Rechner sind das Referenzsystem.
Fehlerbehandlung
Diese Art der Fehlerbehandlung ist inkorrekt:1 errno = 0;
2 int* foo = malloc(10);
3 if (errno) {
4 perror("malloc");
5 exit(EXIT_FAILURE);
6 }
Das liegt daran, dass eine Funktion, die erfolgreich ausgeführt wurde,
die errno beliebig verändern darf (siehe dazu
auch errno(3)). Bei den meisten Funktionen wird im
Fehlerfall ein besonderer Rückgabewert gegeben (z.B NULL im Falle von malloc). Nur wenn so ein Fehler erkannt wird darf
der Wert in errno verwendet werden. Es ist
dann auch unnötig, die errno vorher auf 0 zu
setzen.
Es gibt auch Ausnahmen die gesondert behandelt werden müssen, wie z.B
strtol(3). Das ist dann auf den jeweiligen
manpages vermerkt.
Compilerflags
Zusätzlich zu den vorgegebenen Flags lohnt es sich zum Testen noch ein paar mehr Compileroptionen zu setzen-
-gGeneriert Debugsymbole für besseres Debugging in gdb/valgrind -
-WextraAktiviert zusätzliche Warnungen (tendenziell nervig) -
-Wformat=2Fehler/potentielle Probleme bei der Verwendung von printf/scanf anzeigen -
-WshadowWarnt vor überschriebenen Variablen in Subscopes -
-WconversionWarnt vor problematischen Casts
exec(3) und execve(2)
Beim Lesen von exec(3) sieht man einen Haufen Funktionen die man alle ein wenig unterschiedlich aufrufen muss. Das sind Bibliotheksfunktionen die intern alle den gleichen Systemaufruf execve(2) verwenden. Die Buchstaben am Ende der Funktionsnamen der exec(3)-Familie bedeuten dabei:- l Übergebe argv als Argumentliste
- v Übergebe argv als Array
- p Durchsuche den PATH nach dem übergebenen Programm. Dadurch muss man keine absoluten Pfade zu den Programmen angeben.
argv
muss, egal ob als Liste oder als Array, immer mit
NULL abgeschlossen werden.
Sonstiges
Ich betreue die Rechnerübung am Montag um 12-14 Uhr (zusammen mit Kilian). Den Semesterplan findet ihr auf der Lehrstuhlseite. Bei Fragen zu den Aufgaben (bzw. deren Korrektur, siehe auch Korrekturrichtlinien) und zu anderen SP-Themen könnt ihr mir gerne eine Mail schreiben. Alternativ gibt es als Anlaufstellen- Das SP-Unterforum im FSI-Forum
- Der #sp IRC-Channel (siehe IRC-Guide der FSI)
- Die Allgemeine und die Orga-Maillingliste