Aufgabe 5 - mother: Probleme mit accept():Invalid argument & lstat

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Aufgabe 5 - mother: Probleme mit accept():Invalid argument & lstat
Hallo miteinander,

ich habe die mother eigentlich “zuende” programmiert und bin dabei die mir übergebenen Fehler zu verstehen und zu korrigieren.
Jedoch nach langer Fehlersuche scheiter ich an 2 Problemen zum besseren Verständins was in meinem Programm so vorgeht habe ich die stderr und stdout in Textdateien umgeleitet und werde diese in den Anhang hinzufügen.:

1. Problem:
ich bekomme in der stderr, die ganze zeit die Ausgabe accept(): invalid argument, bzw. auch accept(): Bad file descriptor, hier verstehe ich nicht wie das sein kann? Mir wird ja die mother.o vorgegeben in der die funktion accept() vorkommt.

2.Problem:
meine lstat() funktion gibt mir laut perror, folgende Aussage “lstat: No such file or directory”. Ich übergebe lstat() den zusammengesetzten path (den es eigentlich geben sollte) und eine adresse auf einen struct stat. Was mache ich falsch?

Das Ganze spiele ich mit nc auf meinem Rechner durch. In der einen Konsole gebe ich folgendes ein: echo -e ‘GET / HTTP/1.1\r\n’ | nc localhost 2000

In einer anderen Konsole, starte ich die ./mother mit folgenden Aufruf: valgrind ./mother --wwwpath=/proj/i4sp2/pub/aufgabe5/wwwdir --port=2000 > …/stdout_ausgabe.txt 2>…/stderr_ausgabe.txt

Bin euch für Hilfe und Erklärungen dankbar!

Anhang:
stdout mit detailierten Ausgaben zum debuggen.

Attachment:
stdout_ausgabe.txt: https://fsi.cs.fau.de/unb-attachments/post_137498/stdout_ausgabe.txt


weiterer Anhang:
stderr Ausgabe

Attachment:
stderr_ausgabe.txt: https://fsi.cs.fau.de/unb-attachments/post_137499/stderr_ausgabe.txt


Du machst bestimmt den Verbindungsannahme-Socket irgendwo im Programm mit [m]close()[/m] zu. Bei der [m]sister[/m] war das sinnvoll, weil der Kindprozess selber keine neuen Verbindungen annehmen wird und deswegen mit dem Socket nie mehr etwas anfangen kann. Bei der [m]mother[/m] läuft die Abarbeitung der Anfragen im selben Prozess ab wie die Verbindungsannahme - durch das [m]close()[/m] drehst du dir also quasi selber den Saft ab.

Was das fehlgeschlagene [m]lstat()[/m] angeht, solltest du mal deinen besten Kumpel Valgrind befragen. Kann sein, dass irgendwo beim Zusammenbasteln der Strings was schiefläuft - vielleicht ist das Resultat nicht [m]‘\0’[/m]-terminiert oder so.


Da hast du mit deiner Vermutung recht gehabt. Kaum habe ich das close() auskommentiert, schon waren die accept()-fehlermeldungen weg.
Das problem mit lstat() habe ich auch irgendwie durch viel probieren hinbekommen. Eines der probleme war dass ich den path in einem char[wert] gespeichert habe den ich nicht initialisiert habe. Scheinbar musste ich jedes einzelne char initialisieren bevor dass geklappt hat. Im internet hatte ich folgende Form gesehen die nicht geklappt hat bei mir

Frage hier wäre warum das nicht geklappt hat?

Neues Problem:
beim Auflisten des Ordners …/perl-test/ , wird mir 8-mal „Folien“ aufgelistet, und laut valgrind mache ich bei readdir_r() einen invalid write und später eben auf die elemente einen invalid read… woran könnte das liegen? :-/ (stderr im Anhang)

Attachment:
stderr_ausgabe.txt: https://fsi.cs.fau.de/unb-attachments/post_137506/stderr_ausgabe.txt


Wo ist der Anhang? :wink:


Ich war fest davon überzeugt dass ich ihn hinzugefügt hätte :'D
Wurde jetzt nachträglich hinzugefügt :slight_smile:


→ Du allozierst zu wenig Speicher für die [m]dirent[/m]-Struktur. In der Man-Page ganz unten steht, wie man’s richtig macht.


Also ich habe den Eintrag in der Man-Page eigentlich fast 1:1 abgeschrieben und bekomme beim kompilieren folgende Meldungen:

request-httpx.c: In function ‘handleRequest’:
request-httpx.c:338:27: error: ‘dirent’ undeclared (first use in this function)
request-httpx.c:338:27: note: each undeclared identifier is reported only once for each function it appears in
request-httpx.c:338:35: error: expected expression before ‘)’ token
request-httpx.c:337:11: error: unused variable ‘len’ [-Werror=unused-variable]
cc1: all warnings being treated as errors
make: *** [request-httpx.o] Error 1

In meinen Code-Zeilen steht folgendes:
337: size_t len = offsetof(struct dirent, d_name) + name_max + 1;
338: struct dirent *entry =(dirent *) malloc(len);

Was mache ich falsch? :-/
<dirent.h> und <stddef.h> werden eingebunden.


Also hier fällt mir spontan eigentlich nur auf, dass du hier versuchst, einer Variable vom Typ [m]struct dirent *[/m] einen Wert vom nicht vorhandenen (!) Typ [m]dirent *[/m] zuzuweisen.


Beim Cast vor dem [m]malloc[/m] musst du [m]struct dirent[/m] schreiben, nicht nur [m]dirent[/m].


Oder aber du lässt den Cast einfach weg…

2 Likes

Das funktioniert aber nicht, wenn man bestimmte zusätzliche Flags verwendet. :wink:


Und zwar [m]-x c++[/m]? :wink:

1 Like

Hm, ok. Ich dachte eigentlich [m]-Wextra[/m] mag sowas nicht. Vielleicht hab ich irgendein anderes Flag im Kopf, das aus genau diesem Grund in keinem meiner Makefiles mehr drin steht. Oder aber ein solches (sinnvolles) Flag existiert nicht. :slight_smile:


Der Cast ist in C nicht notwendig, deswegen gibt es da auch kein Flag dafür.

1 Like

Was aber nicht heisst, dass man den Cast nicht dalassen kann um gewisse Fehler wie den oben aufzudecken :slight_smile:


Das war das Problem! :slight_smile:

Ich habe das Gefühl ich bin kurz vorm Ziel, jedoch bekomme ich beim anklicken von beispielsweise „visitors.pl“ folgenden Fehler bei lstat:
request-httpx: z.144:lstat mit path=/proj/i4sp2/pub/aufgabe5/wwwdir/proj/i4sp2/pub/aufgabe5/wwwdir/perl-test/visitors.pl : No such file or directory

Es ist mir schon klar warum das hier ein fehler ist, der Pfad ist ja schlichtweg falsch, und genau hier liegt meine Frage:

Ich bastel mir ja sozusagen im Hintergrund aus den --wwwdir-Flag und der Ausgelesenen Zeile einen Pfad zusammen, ist es so gewollt dass ich überprüfe ob die eingelesene Zeile bereits mein --wwwdir-Flag enthält? Denn wie in meinem Fall zu sehen habe ich das /proj/i4sp2/pub/aufgabe5/wwwdir/ doppelt hintereinander. <_<



Natuerlich kann man lange darueber streiten, mich persoenlich ueberzeugt keine der Stackoverflow-Antworten. Und dass die alle keine Ahnung haben (husthust) merkt man daran, dass die am hoechsten bewertete Antwort ein rechthaberischer Schwaetzer ist der lieber darueber jammert, dass sizeof keine Klammern haben sollte als auf den offensichtlichen Bug der Verwendung von malloc statt calloc in der Frage hinzuweisen.