Description
Board
ESP32-classic
Device Description
Not tried on several boards, but got it reproducible on ESP32-classic.
Hardware Configuration
Version
latest master (checkout manually)
IDE Name
PlatformIO
Operating System
Windows 11 / WSL2
Flash frequency
PSRAM enabled
yes
Upload speed
Description
Assigning an empty string using std::move
may cause a crash.
So also assigning an empty string as result from a function will also eventually end up in crashes.
The fix is extremely simple; the memmove should only be called when rhs.len() > 0
Maybe the check should even be extended to if (rhs.len() && rhs.buffer())
void String::move(String &rhs) {
if (buffer()) {
if (capacity() >= rhs.len()) {
if (rhs.len()) { // <<== This check added
memmove(wbuffer(), rhs.buffer(), rhs.length() + 1);
}
setLen(rhs.len());
rhs.invalidate();
return;
} else {
if (!isSSO()) {
free(wbuffer());
setBuffer(nullptr);
}
}
}
if (rhs.isSSO()) {
setSSO(true);
memmove(sso.buff, rhs.sso.buff, sizeof(sso.buff));
} else {
setSSO(false);
setBuffer(rhs.wbuffer());
}
setCapacity(rhs.capacity());
setLen(rhs.len());
rhs.setSSO(false);
rhs.setCapacity(0);
rhs.setBuffer(nullptr);
rhs.setLen(0);
}
#endif
N.B. it is a bit confusing that buffer()
can return both a nullptr as well as a pointer when it is an empty string.
This might cause other issues as well as the rest of the coding-style in the class suggests it is more like checking for a non-empty string.
N.B.2. This bug is likely present for quite a long time, so maybe also needs backporting?
Sketch
N.B. I did not exactly test this sketch below, but it is a very stripped down gist of the code which is causing crashes in my project.
++
String foo() {
return String();
}
// Important to note that the strings have to be constructed first
// and then assigned a new value.
String bar, working, crashing, crashing_too;
bar = foo();
working = bar;
crashing = std::move(bar);
crashing_too = foo();
Debug Message
Part of crash log, pointing clearly to `String::move`
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x4008b05e PS : 0x00060730 A0 : 0x80160436 A1 : 0x3ffb1760
A2 : 0x3ffb17d8 A3 : 0x00000000 A4 : 0x00000001 A5 : 0x3ffb1770
A6 : 0x3ffb1760 A7 : 0x3ffb1770 A8 : 0x00000000 A9 : 0x00000000
A10 : 0x3ffb1808 A11 : 0x00000001 A12 : 0x00000007 A13 : 0x3ffb1770
A14 : 0x0000004e A15 : 0x0000003f SAR : 0x00000010 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x4008af4c LEND : 0x4008af62 LCOUNT : 0xffffffff
Backtrace: 0x4008b05b:0x3ffb1760 0x40160433:0x3ffb1780 0x40131e06:0x3ffb17a0 0x40101a5f:0x3ffb1890 0x4017312b:0x3ffb1ab0 0x40125bb5:0x3ffb1ad0 0x40157a4f:0x3ffb1c70 0x40152899:0x3ffb1e20 0x400d61fe:0x3ffb1e40 0x400e7d1e:0x3ffb1e60 0x400ecfe2:0x3ffb1e80 0x40137ca5:0x3ffb2000 0x4016a671:0x3ffb2040 0x40124ed5:0x3ffb2110 0x40162daf:0x3ffb2290
#0 0x4008b05b in memmove at /builds/idf/crosstool-NG/.build/xtensa-esp-elf/src/newlib/newlib/libc/string/memmove.c:66
#1 0x40160433 in String::move(String&) at ??:?
#2 0x40131e06 in ESPEasy_TouchHandler::loadTouchObjects(EventStruct*) at ??:?
#3 0x40101a5f in Plugin_123(unsigned char, EventStruct*, String&) at ??:?
#4 0x4017312b in _Z21getDeviceIndex_sorted13deviceIndex_t$isra$0 at ??:?
#5 0x40125bb5 in PluginCall(unsigned char, EventStruct*, String&) at ??:?
#6 0x40157a4f in handle_devices() at :?
#7 0x40152899 in UriGlob::canHandle(String const&, std::vector<String, std::allocator<String> >&) at :?
#8 0x400d61fe in std::function<void ()>::operator()() const at .platformio/packages/toolchain-xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/std_function.h:591
#9 0x400e7d1e in FunctionRequestHandler::handle(WebServer&, http_method, String const&) at :?
#10 0x400ecfe2 in WebServer::handleClient() at ??:?
#11 0x40137ca5 in run10TimesPerSecond() at ??:?
#12 0x4016a671 in _ZN17ESPEasy_Scheduler15handle_scheduleEv$constprop$0 at ??:?
#13 0x40124ed5 in ESPEasy_loop() at ??:?
#14 0x40162daf in app_main at ??:?
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.