Updater::begin picks the 4 KB buffer by total free heap, and does not fall back to 256 B when the allocation fails
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 76/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- cpp
- Domaine
- embedded-iot
Piste de recherche
Lisez cores/esp8266/Updater.cpp autour de UpdaterClass::begin() et _writeBuffer(), puis vérifiez le modèle de flux de Updater.h pour comprendre comment la taille du tampon est utilisée. Vérifiez qu’un tampon plus petit peut être sélectionné lorsqu’une allocation de 4 Ko échoue et que l’effacement des secteurs fonctionne toujours avec des écritures de 256 octets. Le travail est terminé lorsque begin() peut se rabattre sur le tampon plus petit en cas de fragmentation du tas, sans modifier le comportement de la mise à jour.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
What happens
UpdaterClass::begin() chooses its write buffer size from the total free heap:
// cores/esp8266/Updater.cpp, 3.1.2 lines 172-181 (same on master, lines 174-183)
if (ESP.getFreeHeap() > 2 * FLASH_SECTOR_SIZE) {
_bufferSize = FLASH_SECTOR_SIZE;
} else {
_bufferSize = 256;
}
_buffer = new (std::nothrow) uint8_t[_bufferSize];
if (!_buffer) {
_setError(UPDATE_ERROR_OOM);
_reset(false);
return false;
}
Total free heap says nothing about the largest free block. On a fragmented heap the check can pass while a 4096 byte block does not exist. Then new fails and begin() returns false with UPDATE_ERROR_OOM. The 256 byte buffer is never tried.
What I measured
- Core 3.1.2, ESP8266 (GeekMagic SmallTV-Ultra).
ESP.getFreeHeap()= 19.6 KB.ESP.getMaxFreeBlockSize()= 3,888 bytes.
What I did not measure
I did not run the upload in this state. I restarted the device first. That the upload would be refused with UPDATE_ERROR_OOM comes from reading the code above. 19.6 KB is more than 8192, so the 4 KB branch is taken. A 4096 byte allocation cannot fit in a 3,888 byte block.
Why a smaller buffer should be safe
_bufferSize is private and is only used inside Updater.cpp and the Updater.h stream template. The 256 byte case already exists for low free heap (commit 01e1c586, "Updater: if low on heap memory, use smaller write buffer"). _writeBuffer() erases a sector when _currentAddress % FLASH_SECTOR_SIZE == 0, which still works with 256 byte writes.
Proposed small change (sketch, untested)
- if (ESP.getFreeHeap() > 2 * FLASH_SECTOR_SIZE) {
+ if (ESP.getMaxFreeBlockSize() >= 2 * FLASH_SECTOR_SIZE) {
_bufferSize = FLASH_SECTOR_SIZE;
} else {
_bufferSize = 256;
}
_buffer = new (std::nothrow) uint8_t[_bufferSize];
+ if (!_buffer && _bufferSize > 256) {
+ _bufferSize = 256;
+ _buffer = new (std::nothrow) uint8_t[_bufferSize];
+ }
if (!_buffer) {
The first part picks by largest block. The second part is a safety net if the allocation still fails. Either part alone would already fix the case above. I can prepare a PR if this direction is fine.
- Langage dominant
- C++
- Étoiles
- 16.7k
- Forks
- 13k
- Merge moyen
- 1 j 2 h
- PR mergées (30 j)
- 7
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de esp8266/Arduino
-
Typo in Scan Class DocumentationPeut-être pris @MukundaKatta l’a pris il y a 207 jours. Ouverte
Difficulté 1/5 Moins d'une heure Accessibilité débutants 70/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
esp8266/Arduino#9203 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 52/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 65/100
esp8266/Arduino#9324 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 42/100
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de esp8266/Arduino
Issues similaires
-
status:needs-triage
Difficulté 2/5 1-3 heures Accessibilité débutants 74/100
PX4/PX4-Autopilot#29698 ·
Les mainteneurs répondent en général sous 1 jour
-
go perft exits when EvalFile is unavailablePeut-être pris @Muawiya-contact l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
official-stockfish/Stockfish#7292 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 77/100
arvidn/libtorrent#9149 ·
Les mainteneurs répondent en général sous 1 jour
-
Upstream report: MSVC rejects a designated initializer in a dependent template argument (C2131)Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
rhalbersma/tabula#72 ·
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour