Hi Martinus,
Thanks for the reply. I came across the bug while trying to develop a new plugin. I was trying to give appropriate error messages using constructions similar to some of yours such as :
Code: Select all
LoadTaskSettings(event->TaskIndex);
String log = F("200 Device ");
log+=ExtraTaskSettings.TaskDeviceName;
log+=" Value ";
log += ExtraTaskSettings.TaskDeviceValueNames[0];
log += " - Initially set to 0 [OFF]";
addLog(LOG_LEVEL_INFO, log);
I was getting surprising results and discovered the error I mentioned previously in LoadTaskSettings. As you mentioned, there are other problems as well and I think some of these may be related to frequent use of dynamic memory allocation.
I have been looking a bit further into the code and notice that String variables are used heavily throughout ESPEasy - and not always in the safest way. A particularly bad example can be found in the module WebServer.ino where you will find the following call to PluginCall :
Code: Select all
PluginCall(PLUGIN_WEBFORM_LOAD, &TempEvent, reply);
'reply' is a String variable to which successive strings have been dynamically added until it is about 4700 characters long by the time PluginCall is invoked!! Each of these appends copies the original string to a temporary variable, appends the new string and then copies back which results in a very fragmented stack. Some plugins ( for example P012 ) make several more appends to 'reply' which add an additional 1500 characters to this already enormous string!! As new functionality has been added to ESPEasy in recent releases, 'reply' has grown until, in my case at least, it results in a stack crash every time the P012 webform is loaded.
I can easily workaround this problem for now as follows :
Code: Select all
String Treply;
PluginCall(PLUGIN_WEBFORM_LOAD, &TempEvent, Treply);
reply+=Treply;
This shortens the string which is passed to PluginCall thereby reducing the fragmentation and avoids the stack crash. However, it is not a final solution.
You probably know better than I do that String operations allocate memory dynamically and in ways that are hard to predict. Dynamic memory allocation almost always causes memory fragmentation which will eventually lead to a stack crash. It's just a matter of time! For embedded software, it is best to avoid String variables altogether - and certainly huge ones like 'reply'. Better to allocate appropriate char arrays wherever possible.
The problem for ESPEasy is that removing String variables would also mean changing the calling signature of all plugins and I can see that you probably don't want to do that. As a stopgap measure, I think that eliminating the enormous strings used in WebServer (or at least breaking them up into smaller strings) would help a lot.
I hope you don't take the above as criticism - it is meant to be helpful. In general I really like the software and have found it to be really flexible and easily expandable - I wish I had thought of it!
Thanks for your help
N