-
Notifications
You must be signed in to change notification settings - Fork 1.3k
request handler panic in core_esp8266_main.cpp when using readString on SPIFFS #1
Comments
The main problem is that you use readString() which calls yield internally ( not optimistic_yield like SPIFFS) so you always try to switch the context and that triggers the panic. Try to read the bytes into a char buffer and turn that into a string if you need to manipulate the string. |
Seems |
yeah, I'll look into those a you showed a problem I did not expect :) have you tried casting the callback? g_server.on("/index.html", (ArRequestHandlerFunction)handleRoot); also you handleRoot is defined above where you attach on() right? |
if we fix the core to not yield all of the time maybe you will be able to use the String functions :) I prefer that, than showing workarounds |
I've got this now (omitting the prints):
but it gets stuck:
It's also quite ugly that we need the memory twice- for buffer and string. Any ideas? ps.: cast is fine! |
What are you using the string for? Maybe I can give ideas if I know more of what you want to acomplish with it :) also above you free the buf, but you might be doing it too soon? what is E:M 7000 ? :D never seen that |
can you hack into Print.cpp in the core and remove the yield inside timedRead and see if you can use the readString() |
I'm just using it to run some replacements:
Most things are json services, but some data is required upfront.
Mhm. Can't find
Must be coming from core or sdk. Apparently telling me that my sketch is borked :( |
optimistic_yield should be 10000 or more |
Same result using
I'm lost... |
what about without any yield at all |
Same thing. scratch head |
scratching head as well |
The longer I keep looking the more I think its is in the wrong place. This:
produces this:
I'll build a minimal sketch for you. |
See http://pastebin.com/5MktDN10 and https://gist.github.com/andig/4797200d6bfb1fd4560b |
If you update the handler function from the last example like this:
It will immediately crash. What prevents |
Last update for today: if I put the read/ string conversion part into |
if it's in setup it is running on the loop thread and there things are fine. It's something else and I'll investigate it :) have to make it work |
following is the exact handler I have attached to test your function. I have 0 problems, response time is 80-90ms and webpage shows as expected. I do not Serial.print ;) oh and no leaks either server.on("/test", [](AsyncWebServerRequest *request){
String indexHTML = F("<!DOCTYPE html><html><head><title>Test</title></head><body><h1>Test</h1></body></html>");
File indexFile = SPIFFS.open(F("/index.html"), "r");
if (indexFile) {
//indexHTML = indexFile.readString();
char *buf = (char*)malloc(indexFile.size()+1);
if (buf) {
indexFile.read((uint8_t *)buf, indexFile.size());
buf[indexFile.size()] = '\0';
}
indexFile.close();
indexHTML = String(buf);
free(buf);
char buff[10];
uint16_t s = millis() / 1000;
uint16_t m = s / 60;
uint8_t h = m / 60;
sprintf(buff, "%02d:%02d:%02d", h, m % 60, s % 60);
// replace placeholder
indexHTML.replace("[esp8266]", String(ESP.getChipId(), HEX));
indexHTML.replace("[uptime]", buff);
indexHTML.replace("[ssid]", WiFi.SSID());
indexHTML.replace("[wifimode]", (WiFi.getMode() == WIFI_STA) ? "Connected" : "Access Point");
}
request->send(200, "text/html", indexHTML);
}); index.html <!DOCTYPE html>
<html>
<head>
<title>Hello SPIFFS</title>
</head>
<body>
<h2>ESP8266</h2>
<h3>ChipID: [esp8266]</h3>
<h3>Uptime: [uptime]</h3>
<h3>SSID: [ssid]</h3>
<h3>Mode: [wifimode]</h3>
</body>
</html> |
Much appreciated. I've only had time for a quick test this morning and can confirm that it didn't crash. Moving back to additional steps I could get the crash again and immediately. If you have 10 minutes could you also test these changes:
I'll retest the same tonight. |
I have the OTA running at all times. It will not interfere with the server at all :) |
hah! I got the email but your message is not here |
Yes, forgive me. Every time I think I've found a pattern its gone on retest. Don't want you chasing red herrings... |
Ok. More tests. Working every time, regardless of how I call the handler, with your index.html. Assumption: timing issue due to the bigger file. As ESP has 40k of free RAM definitely not out of memory. If you can't repro with my file, maybe duplicate the file content. |
6 684 bytes while it might be under the available RAM it's more than you can easily allocate at the same time and work on. It's quite the size for transferring as string as well. On the way out you pass through a few buffers and they add to the momental ram usage... |
When you read your big html, does it come out ok? like have you tried reading it in the loop and printing the result to serial for example? |
still testing .. |
Ok. These are the results. I can work reliably with buffers of around 4kb size with the logic above (allocate, read, convert to string, replace). That also means that in the process we need at least 2x4kb memory for buffer+string or string+replacement string. I've then hacked
That approach will only use the buffer once. While working at 4k it still fails at 6.6k most of the time. I believe this is some indication that the root cause is a timing problem rather than a memory problem. If you agree- could anything be done about that? If not then I understand enough now on how to change the architecture of my html and js... |
I don't think it's timing as the server can very well send much larger content. |
and are you saying that you sometimes can allocate that 6.6k, replace the stuff inside and send out successfully? |
I'm going through the code wandering what it might be. I impose no restriction in the handler on the length of the string, but I do copy it since it's async and will return back to you and you will free your string. So maybe allocating over 8k at a time is a problem? who knows... |
I was thinking of having that string outside and using a callback response to send it in chunks. |
Yeah, you're right- I guess we just give up on this one and I change the implementation. Async is blazingly fast in comparison, excellent job!
|
I'm beating my head currently because I have problems with 1.5.1 when uploading large files and my file system is already full of deleted pages (if you have any idea how spiffs works). So when that hits, writes to the file system slow down and lwip loses packets on retransmission because it can not handle the new packets so quick anymore. sdk 1.3 is fine and never loses a beat, but the networking on it is 3 times slower :( |
Sounds a little like my original issue where igor said its memory loss/ corruption inside the mac layer. Sounds like the kind of shaky basis that you really don't want to build one... |
My feeling is that the network layer is somewhat borked. Isnt your scenario exactly what tcp send/receive window scaling is responsible for? |
yes. on tcpdump all looks fine. The esp asks for retransmission and gets it, ut either the retransmitted packets or some other packets there get lost somewhere. Just lost! the Async TCP digs about as far down as maybe even too far, but still do not get the packet. SO they broke something ;) 1.3 is fine with the same behavior on the stack |
Would you happen to be in Germany for a beer? |
sadly no :( about 2K kilometers far |
Let me know- I owe you. If you're into smart metering feel free to take a look at http://volkszaehler.org, an opens source smart meter where I'm part of the dev team. |
you know anything about RS434? I have a module and power meter but no clue how to talk to it. No docs and what I have found so fat on internet is not much |
Let me ask my hardware genius ;) On Fri, Jan 22, 2016 at 7:43 PM, Me No Dev [email protected] wrote:
|
Do you mean rs485? What type of module and meter, any docs? |
yeah :( if I had docs... I have a couple of those, they measure electrical consumption. Have RS and pulse output and an LCD. All came in a blank box. No docs. I was hoping there is some standard way to talk to those |
No model on the meter or module? Photo? |
I think the problem is the modbus/mbus protocol. There are several libraries around but I've not managed to understand the differences. You could however use the S0 output, connected to gpio via optical transforder and count the s0 impulses? |
I was hoping to get more information than that from the device. It keeps tracks of things inside and I imagine that data is available through the RS |
Set compatibility only with Espressif 32
…response-finished-pull-try1 Explicitly close socket after response has entered finished state
Manual merge from anton-zolotarev:master
Follow-up of esp8266/Arduino#1458
The text was updated successfully, but these errors were encountered: