LightWeight IP: Puffer wird nicht freigegeben

8

Ich verwende einen TCP / IP-Stack namens lwip . Ich habe unten eine Funktion implementiert, um Datenpakete zu senden, inspiriert von einer ähnlichen Rückruffunktion, die Datenpakete empfängt.

Jedes Mal, wenn ein Paket empfangen wird, erstelle ich einen Puffer mit der Funktion pbuf_alloc . Dann sende ich das Paket mit udp_sendto . Schließlich gebe ich den Puffer mit pbuf_free frei. (Siehe den Code unten.)

Aus irgendeinem Grund gibt pbuf_free den Puffer nicht frei. (Ich bekomme einen Pufferüberlauf nach n -Pakete, wobei n die Poolgröße ist.) Das lwip wiki warnt das:

  

Der Netzwerktreiber kann auch nicht davon ausgehen, dass der PBUF-Speicher ist   tatsächlich freigegeben, wenn es pbuf_free aufruft.

Wie kann ich pbuf_free zwingen, meinen Puffer freizugeben? Wie wird der Pufferüberlauf vermieden?

(Meine Implementierung unten.)

%Vor%     
Randomblue 18.06.2012, 13:28
quelle

4 Antworten

7

Welche Version von lwIP verwenden Sie? Abhängig von verschiedenen Versionen variieren die Antworten sehr.

Die memp_malloc () - Zuweisungsfunktion, die in pbuf_alloc () aufgerufen wurde, ist fehlgeschlagen oder die Verkettung von pbufs ist fehlgeschlagen. So gibt sie NULL zurück.

pbuf_alloc () gibt auch NULL zurück, wenn die übergebenen Argumente auch NULL enthalten (aufgrund der Überprüfung von NULL-Argumenten).

Können Sie in neueren Versionen anzeigen, welchen Wert das Makro MEMP_OVERFLOW_CHECK enthält? Das lwIP zeigt ein anderes Verhalten, wenn der Makrowert & gt; = 2 ist.

Ein weiterer Grund könnte sein, dass Sie bei Verwendung von Multi-Threading die Sperrmechanismen in pbuf_alloc () fehlschlagen lassen und NULL zurückgeben könnten.

Einige Versionen erfordern, dass Sie pbuf_init () aufrufen, bevor Sie pbuf_alloc () aufrufen.

Sie können dies versuchen:

%Vor%

PBUF_REF wird keinen Pufferspeicher für pbuf zuweisen. Der pbuf sollte nur in einem einzelnen Thread verwendet werden und wenn der pbuf in die Warteschlange gestellt wird, sollte pbuf_take aufgerufen werden, um den Puffer zu kopieren.

Sie können auch PBUF_RAM versuchen, das Puffer im RAM reserviert.

Für weitere Informationen können Sie auch die Quelldateien der von Ihnen verwendeten Version von lwIP durchsuchen.

    
askmish 23.07.2012, 12:10
quelle
6

Die einfachste Lösung scheint zu sein, den Puffer static zu machen, d. h. den gleichen Puffer für jeden Aufruf wiederzuverwenden:

%Vor%

Wenn in Ihrem Szenario der Treiber entladen / neu geladen wird, wird Speicher ausgelaufen. Um das zu beheben, mache den Puffer statisch außerhalb der Funktion IAP_tftp_send_data_packet() und rufe pbuf_free() auf, wenn der Treiber entladen wird (vorausgesetzt, lwip sagt es dir).

    
unwind 18.06.2012 13:40
quelle
0

Nur ein vorübergehender Gedanke, möglicherweise völlig unsinnig. In diesem Code:

%Vor%

... ist es möglich, dass bytesRead den Wert 513 - TFTP_DATA_PKT_LEN_MAX annimmt?

Wenn es passierte, würde die Anforderung, Nullbytes zuzuweisen, nicht fehlschlagen? (Dies könnte getestet werden, indem der Wert von bytesToSend bei Pufferüberlauf gedruckt wird und überprüft wird, ob es ungleich Null ist).

    
LSerni 21.08.2012 17:58
quelle
0

struct pbuf repräsentiert keine kontinuierliche Speicherregion. Es ist eher eine Kette von Speicherorten. Daher wird dies im allgemeinen Fall nicht funktionieren:

%Vor%

Sie müssen Ihre Daten zerstreuen. Das memcpy () aus dem Code-Snippet kann den Payload-Puffer überlaufen und alle Arten von Nebenwirkungen verursachen, einschließlich der Unfähigkeit, die pbuf-Kette sauber zu befreien.

    
Maxim Kharchenko 26.07.2013 09:34
quelle

Tags und Links