Go Down

Topic: Webserver hängt sich aus (Read 1 time) previous topic - next topic

jurs


    char sReturnCommand[32];


Beim Einlesen von Zeichen prüfst Du nirgends, ob nicht eine Zeile in der Client-Anforderung möglicherweise länger als 31 Zeichen ist, dadurch besteht die Gefahr, über den Variablenbereich hinaus in fremde Datenbereiche zu schreiben.

Sepron


Editieren
Hallo
Danke für die Rückmeldung

Ich habe jetzt die htmlcode strings mit F() versehen und der Sketch wurde kleiner, konnte bis jetzt auch kein Freeze erkennen.
Das mit den
Code: [Select]
char sReturnCommand[32];
Verstehe ich leider nicht. Wie muss ich den Code umschreiben, dass er nicht in fremde Datenbereiche schreibt?
Gibt es sonst noch Kleine kniffe, wie ich das Risiko des Einfrierens verringern kann oder, wenn es so weit kommt, er selbstständig neu startet?
Ich habe gelesen, dass man einen Pin mit reset brücken kann und ihn nach einer Reset den Neustart durchführen lässt, was aber nicht sonderlich gesund wäre.

Grüße aus dem Rheinland

michael_x

Quote
Wie muss ich den Code umschreiben, dass er nicht in fremde Datenbereiche schreibt?
Hier:
Code: [Select]
if (nCommandPos>-1) {
  sReturnCommand[nCommandPos++] = c;
}

... solltest du, nach jurs' Meinung, eine Bremse einbauen.
z.B.
Code: [Select]
if (nCommandPos>-1 && nCommandPos < 31) {
  sReturnCommand[nCommandPos++] = c;
}


Aber wenn der server nicht von einem x-beliebigen client mit zu großen Kommandos gequält werden kann, ist das halb so wild.
Falls 31 Zeichen sicher reichen.

jurs


Verstehe ich leider nicht. Wie muss ich den Code umschreiben, dass er nicht in fremde Datenbereiche schreibt?


Siehe Vorschlag von Michael.

Beim nochmaligen Drüberschauen über Deinen Code habe ich gesehen, dass Du doch an einer Stelle noch etwas gegen das Schreiben über das Arrayende eingebaut hast, und zwar scheinst Du die Schleife bei Überschreiben einer bestimmten Länge zu unterbrechen:
if (nCommandPos > 30) ...

Aber der ganze Aufbau von Datenstruktur und Programmlogik scheint mir völlig verquer zu sein:
Code: [Select]

char*  httpServer()
...
char sReturnCommand[32];
...
return sReturnCommand


Rückgabewert für die Funktion httpServer() soll ein Ponter sein.
Du deklarierst innerhalb der Funktion ein Char-Array (Gültigkeit des Char-Arrays also nur innerhalb der Funktion)
Und lieferst einen Pointer auf das Char-Array zurück.

Wenn Du hinterher irgendwelche Aktionen mit dem auf diese Art zurückgelieferten Pointer ausführst, z.B. Stringvergleiche, dann ist nicht sichergestellt, dass da das abläuft, was ablaufen soll. Da das definierte Array mit verlassen der Funktion ungültig geworden ist, ist der der Speicherbereich danach als frei gekennzeichnet. Der nächste auftretende Interrupt kann genau diesen frei gewordenen Speicherbereich wieder für etwas anderes verwenden.

Das sieht für mich völlig fehlerhaft programmiert aus, wenn Du versuchst mit Pointern auf ungültig gewordene Variablenbereiche außerhalb des Gültigkeitsbereichs zuzugreifen.

Das würde ich jedenfalls nochmal überprüfen, wo Du möglicherweise mit Pointern auf RAM-Speicher zugreifst, dass das alles seine Richtigkeit hat.

Bitklopfer



.....
Ich habe gelesen, dass man einen Pin mit reset brücken kann und ihn nach einer Reset den Neustart durchführen lässt, was aber nicht sonderlich gesund wäre.

....



Nun das geht auch rein Softwaremäßig, und zwar so:
asm("JMP 0");  // Und Sprung nach RESET

So mache ich einen RESET nachdem ich die SD-Karte entfernt hatte und wieder neu initialisieren will...das braucht auch noch
einen Reset weil die SD-Lib da einen Bug hat.


Go Up