LEAmDNS: _parseResponse keeps every answer record of a packet on the heap, so one large answer can abort with out of memory
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 52/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- arduino, cpp
- Ambito
- embedded-iot
Direzione di ricerca
Start in libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp: trace _parseResponse through _readRRAnswer and _processAnswers, then compare with _parseQuery's record handling. The report proposes processing and freeing each response record before reading the next; done means response handling no longer retains all packet records at once while preserving probe and service query behavior. The reporter says they have a patched copy, but provides no test or captured packet.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What happens
An ESP8266 (core 3.1.2, a GeekMagic SmallTV-Ultra with about 6 KB of free heap while running) restarted after
11.4 hours with an out-of-memory abort inside LEAmDNS. Our crash record, decoded with addr2line:
operator new (288 bytes) failed
<- MDNSResponder::_readRRAnswer
<- MDNSResponder::_parseResponse
<- MDNSResponder::_parseMessage
<- MDNSResponder::_process
free heap 952 bytes, largest free block 248 bytes
The lowest values recorded before, during those hours, were about 4.4 KB free and a 1.5 KB largest block. So
about 3.5 KB went within a moment. The sketch only advertises (MDNS.begin, addService, addServiceTxt, and
MDNS.update() in loop()); it sends no queries.
Why, from reading the code (master, libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp)
_parseResponsereads answers only while a service query waits or a probe runs (line 742-743). Probing runs
afterMDNS.beginand again after every interface status change (LEAmDNS.cpp, thestatusChangeCBthat
calls_restart()), for example a Wi-Fi reconnect.- In that state, every record of the incoming packet (
ANCount + NSCount + ARCount, taken from the packet
header) is read with_readRRAnswerinto its own heap object and kept in a list (lines 764-775). - The list goes to
_processAnswersas a whole (line 794) and is freed only after that (lines 804-810).
So the heap needed grows with the number of records in someone else's answer. A phone, TV or speaker that
answers with many records during the probe window can take several KB at once. new aborts on failure in this
core, so the library's own checks for a failed allocation never run, and the result is a restart.
What we did not measure: we have not captured the packet, and we don't know for sure that a reconnect came just
before. That part is our reading of the code.
_parseQuery handles known answers differently: it frees each record right after reading it (so one record at a
time), which is why we think the same can work for responses.
Possible fix
Handle each answer record in _parseResponse as soon as it is read, and free it before reading the next, so the
peak is one record instead of the whole packet. That means splitting _processAnswers so it can take one record
at a time. A simpler, partial alternative: skip (read past without allocating) records whose names cannot
concern this responder.
We are trying the first approach in a patched copy for our own firmware and can open a PR if this direction is
welcome.
- Lingua principale
- C++
- Stelle
- 16.7k
- Fork
- 13k
- Merge medio
- 1g 2h
- PR unite (30g)
- 7
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di esp8266/Arduino
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
esp8266/Arduino#9342 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Typo in Scan Class DocumentationForse già presa @MukundaKatta l’ha presa 207 giorni fa. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
esp8266/Arduino#9203 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 65/100
esp8266/Arduino#9324 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 42/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di esp8266/Arduino
Issue simili
-
status:needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
PX4/PX4-Autopilot#29698 ·
I maintainer di solito rispondono entro 1 giorno
-
go perft exits when EvalFile is unavailableForse già presa @Muawiya-contact l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
official-stockfish/Stockfish#7292 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
arvidn/libtorrent#9149 ·
I maintainer di solito rispondono entro 1 giorno
-
Upstream report: MSVC rejects a designated initializer in a dependent template argument (C2131)Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
rhalbersma/tabula#72 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno