Skip to content

Crash when sending content from flash to client using the webserver #596

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
renzenicolai opened this issue Jul 23, 2015 · 29 comments
Closed

Comments

@renzenicolai
Copy link

I get this error using the stable, staging and latest (compiled from source) version of the arduino package.

Exception (3):
epc1=0x4000bef4 epc2=0x00000000 epc3=0x00000000 excvaddr=0x40243566 depc=0x00000000

ctx: cont
sp: 3ffec940 end: 3ffecbd0 offset: 01a0

>>>stack>>>
3ffecae0:  40243566 00000000 00000000 00000030  
3ffecaf0:  00000000 00000000 3ffeaec8 4020244a  
3ffecb00:  3fff7120 00004526 00004526 00000030  
3ffecb10:  3fff65b8 00000000 00000000 4020742e  
3ffecb20:  00000000 00000000 3ffeaec8 40207a7d  
3ffecb30:  00000011 3fff6c08 00000003 00000003  
3ffecb40:  3fff7060 0000001e 0000001e 402052bd  
3ffecb50:  3ffea360 00000000 000003e8 3ffebbb0  
3ffecb60:  00000000 3fff70e8 0101a8c0 3ffecbfc  
3ffecb70:  3fffdc20 000003e9 3ffeaec8 40207b6d  
3ffecb80:  3ffea360 00000000 000003e8 000147a4  
3ffecb90:  3ffeaee0 3fff70e8 00000016 40102185  
3ffecba0:  40201cdd 00000000 00000000 402044f6  
3ffecbb0:  3fffdc20 00000000 3ffecbf4 40201d3a  
3ffecbc0:  00000000 00000000 3ffebbb0 40100378  
<<<stack<<<

 ets Jan  8 2013,rst cause:1, boot mode:(1,7)


 ets Jan  8 2013,rst cause:4, boot mode:(1,7)

wdt reset

server.on ("/style.css", []() { server.send ( 200, "text/css", DATA_css ); } );

Data:

const char DATA_css[] PROGMEM = R"=====(
body {margin: 0px; padding: 0px; font-family: "Open Sans", sans-serif; font-color: #000; font-size: 14px; background-color: #F2F2F2;}
div.header {position: absolute; left: 0px; right: 0px; top: 0px; background-color: #363636; color: #FFF; margin: 0px; padding: 0px; padding-bottom: 0px; height: 55px;}
div.header h1 {padding: 0px; margin: 0px; padding-top: 5px;}
div.header h1 a {color: #FFFFFF; text-decoration: none;}
div.header .float_left {float: left; padding-top: 5px;padding-left: 10px;}
div.header .float_left h1 {margin: 0px; float: left; padding: 0px; padding-left: 5px; padding-right: 10px; font-size: 35px; font-weight: bold;}
div.header .float_left h1 .logo1 {color: #00AEEF;}
div.header .float_left h2 {margin: 0px; float: left; padding: 0px; padding-left: 5px; padding-right: 10px; font-size: 20px; padding-top: 10px;}
div.header .float_left form {float: left; margin-top: 3px;}
div.header .float_right {float: right; margin: 0px; margin-right: 20px; padding: 0px; height: 100%;}
.mobile_menu {width: 100%; margin-top: 50px; font-size: 30px; text-align: center; }
.mobile_menu a {display: block; width: 100%; color: #FFFFFF; height: 40px; background-color: #363636; text-decoration: none; }
.mobile_menu a:hover {background-color: #00AEEF;}
div.header .float_right a {display: inline-block; color: #FFF; text-decoration: none; padding-bottom: 0px; padding-top: 20px; padding-left: 10px; padding-right: 10px; margin: 0px; height: 35px;}
div.header .float_right a:hover {background-color: #00AEEF;}
.main{width: 600px; margin: 0 auto; margin-top: 100px; padding: 15px; border-color:#000000; border-width: 1px; border-style: solid; background-color: #FFFFFF;}
.main table { border-collapse: true; border-width: 0px; }
.main td { border-collapse: true; border-width: 1px; border-style: solid; border-color: #CCCCCC;}
.home a { display: block; height: 20px; width: auto; text-decoration: none; background-color: #363636; color: #FFFFFF; padding: 5px; }
.home a:hover { background-color: #00AEEF; }
.row {width: 100%; height: 40px; font-size: 15px; margin: 0px; }
.row .left { float: left; padding-top: 7px; }
.row .right {float: right; }
hr{ color: #000; background-color: #000; height: 1px; border: none; width: 100%;}
.center { float: center; width: 100%; text-align: center;}
.center table {text-align: left; width: 150px; margin-left: 75px;}
@media (min-width: 500px) {.home{ width: 300px; margin: 0 auto; padding: 15px; border-color:#DADADA; border-width: 1px; border-style: solid; background-color: #FFFFFF;} .wide{ width: 500px;}}
@media (max-width: 499px) {.home{ left: 3px; right: 3px; margin: 0px; padding: 0px; border-color:#DADADA; border-width: 1px; border-style: solid; background-color: #FFFFFF;}}
@media (max-width: 699px) {div.header .float_right { visibility: hidden;}}
@media (min-width: 700px) {.mobile_menu {visibility: hidden; height: 0px;}}
)=====";
@igrr
Copy link
Member

igrr commented Jul 23, 2015

server.send doesn't seem to be compatible with PROGMEM variables. It expects the data to be in RAM, and doesn't take possible alignment issues into account.
Adding PROGMEM support to WebServer would be an improvement.

@renzenicolai
Copy link
Author

The weird thing is that this function works, even though the data is in flash.
This same function fails with the same exception when using it on the css stylesheet that I posted earlier.

void handleLogo() {
  WiFiClient client = server.client();
  handleStaticHeader(client, sizeof(DATA_logo), "image/png");
  client.write(DATA_logo, sizeof(DATA_logo));
  client.stop();
}

Because flash data apparently isn't supported that well, how can I copy the flash data to a buffer in ram before sending it?

@igrr
Copy link
Member

igrr commented Jul 23, 2015

Yes you can copy PROGMEM data into RAM via String:

String content(DATA_css);
server.send(200, "text/css", content);

@renzenicolai
Copy link
Author

server.on ("/style.css", { server.send(server.client(), "text/css", String(DATA_css) ); } );

Still crashes the ESP

Exception (3):
epc1=0x4000bf64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x40248089 depc=0x00000000

ctx: cont 
sp: 3ffec930 end: 3ffecbd0 offset: 01a0

>>>stack>>>
3ffecad0:  3ffeaec8 3ffe8c54 00000001 402039b5  
3ffecae0:  3ffea360 00000000 000003e8 00000030  
3ffecaf0:  3ffecb80 3fff7160 00000000 00000000  
3ffecb00:  00000000 3fffdc20 3ffecbfc 00000030  
3ffecb10:  3fff65b8 00000000 3ffeaec8 4020743e  
3ffecb20:  00000000 00000000 3ffeaec8 40207a8d  
3ffecb30:  0000000a 3fff70b0 00000003 00000003  
3ffecb40:  3fff70e8 00000017 00000017 3ffebaa0  
3ffecb50:  3fffdc20 00000000 40201cbe 3ffebbb0  
3ffecb60:  402015a2 00000001 3ffeaec8 3ffecbfc  
3ffecb70:  3fffdc20 00000396 3ffeaec8 40207b7d  
3ffecb80:  3ffea360 00000000 000003e8 00009ef9  
3ffecb90:  3ffeaee0 3fff7160 00000016 40102185  
3ffecba0:  40201cdd 00000000 00000000 40204506  
3ffecbb0:  3fffdc20 00000000 3ffecbf4 40201d3a  
3ffecbc0:  00000000 00000000 3ffebbb0 40100378  
<<<stack<<<

("server.on ("/style.css", { String content(DATA_css); server.send(server.client(), "text/css", content ); } );" too)

@renzenicolai
Copy link
Author

I uploaded my sketch to my webserver, you can download it here: http://rnpl.us/code.zip

Maybe that helps while debugging the problem.

@igrr
Copy link
Member

igrr commented Jul 23, 2015

/cc @Makuna

@patjazz
Copy link

patjazz commented Jul 23, 2015

  • I have the same problem ( http://www.esp8266.com/viewtopic.php?f=29&t=4060 ). It seems to me important as RAM is small and FLASH is the good place for all static data in a WEB/net environnement.
  • I have the same problem with fonts datas... :-(
  • I have the idea that 'multiple' PROGMEM is the problem ?

Regards... And thanks for all the job you are doing !

@renzenicolai
Copy link
Author

@patjazz: Sometimes it works with two progmem instances, but I've not yet been able to find a pattern in when it works and when it doesn't. My guess is that it fails above a certain size.

(Wild guess, big chance it's bullshit: could it be that the flash is divided in pages and that the first PROGMEM instance fits into the first page but the second does not? (Then while reading the ESP fails because it only reads the first page and then tries to read more data than what it read from the flash?)

@martinayotte
Copy link
Contributor

My thought about new WebServer needs :
http://www.esp8266.com/viewtopic.php?f=29&t=4060&p=24039#p24039
But the main issue is that WebServer doesn't deal with PROGMEM anyway.
It build again a String in RAM to add header, and then pass it to sendContent() function which is in fact sending the content with multiple chunks of HTTP_DOWNLOAD_UNIT_SIZE (defined as 1460).
What we need is to have a fix in WebServer by adding a new send() and a new sendContent() functions which should deal with PROGMEM separately from the header, having the header in RAM and then sending content chucks directly from PROGMEM using memccpy_P() (defined in pgmspace.cpp) until the last chunk.

@Makuna
Copy link
Collaborator

Makuna commented Jul 23, 2015

With Progmem, you really need to look closely at the Arduino docs, the way it was original designed is not how I would have done it, but it is the way it is in this project for compatibility.

The core of the problem is, the compiler can't tell the difference between these two variables to decide which function to call; as the PROGMEM doesn't not effect the type, it only effects where in memory the data is stored.

const char stringInFlash[] PROGMEM = "in flash";
const char stringInRam[] = "in ram";

But the memory location they are stored at have different requirements. Specifically, in flash, the data pointer must always be 32bit aligned and reads are always 32bits. But the same code reads both flash and ram. So if the code tries to read one byte at a time, it will cause an exception.

If you use the above "stringInFlash" variable in program method (end in _P), then there is an implied knowledge that the passed variable is in flash and it does the right thing in the method.
If you use the same variable to try to call a method that has versions that can take flash memory, then the variable is best defined differently so that the right method is picked by the compiler.

So, in your example, you have

server.on ("/style.css", []() { 
        String content(DATA_css); 
        server.send(server.client(), "text/css", content ); 
    } );

since it can't tell DATA_css is in flash, you need to let it know, by casting it like this

server.on ("/style.css", []() { 
        String content(reinterpret_cast<const __FlashStringHelper *>(DATA_css)); 
        server.send(server.client(), "text/css", content ); 
    } );

This assumes you have enough RAM to temporally store the complete string.

FYI: I glanced at the Server code to see how hard it would be to convert to have a send_P(), unfortunately it is not simple; but in the long run I agree it would be interesting. As @martinayotte mentions, a good start is to separate out the header and content for sending, then the rest gets simpler.

@patjazz
Copy link

patjazz commented Jul 23, 2015

Why the compiler and/or linker can't do an ALIGN 32 ? even if we loose 3 bytes ? as they know that the data will stay in flash ? (if it is an alignment problem....)

@Makuna
Copy link
Collaborator

Makuna commented Jul 23, 2015

@patjazz The compiler does create the data aligned, but you can't read a single byte, which most string methods assume they can do. You can only read 32bits (as you can't reference the other bytes due to the pointer must remain 32bit aligned). And the compiler doesn't know anything about where it stored, this seems to be dark spot in C/C++ where it doesn't track this information with the type.

I wish that Arduino guys had created a more solid solution for this, like providing a real pointer wrapper and not the kludge _FlashStringHelper.

@martinayotte
Copy link
Contributor

Hi Makuna,
I think that adding new send_P() and sendContent_P() functions should be quite straight forward, (except if there are pitfalls somewhere I didn't saw beforehand).
Although I miss the famous "time ingredient" these days, maybe I can try to get it patched, but that won't warranty to get it into an official PR soon.

EDIT : coding should be simply copy/paste and adding the memccpy_P(), it should take 5 mins. But testing and commit can take hours ... :-)

@Makuna
Copy link
Collaborator

Makuna commented Jul 24, 2015

@martinayotte If it still has to allocate the full buffer inside to copy memory, sure, but I think the right solution is to try to "chunk" it so the memory allocation is smaller allowing a large content size to be used without taking a larger memory footprint.

Oh yeah, testing ;-)

@Links2004
Copy link
Collaborator

Note: more then 1460 Byte can note be send by TCP at one. so bigger buffer make no sense.

@Makuna
Copy link
Collaborator

Makuna commented Jul 24, 2015

p.s. I am working on exposing a send_P();

void send_P(int code, PGM_P content_type, PGM_P content);

@igrr
Copy link
Member

igrr commented Jul 24, 2015

Great!
IMO content_type doesn't really need to be PGM_P, it's just a few bytes.

On Fri, Jul 24, 2015, 20:20 Michael Miller [email protected] wrote:

p.s. I am working on exposing a send_P();

void send_P(int code, PGM_P content_type, PGM_P content);


Reply to this email directly or view it on GitHub
#596 (comment).

@Makuna
Copy link
Collaborator

Makuna commented Jul 24, 2015

If the compiler doesn't do string duplication removal, and you call send_P is many locations, those can add up quickly.
I am sure there are some people who would want it, so rather than add one that does and one that doesn't, it seems cleaner to just require it. Thoughts?

@renzenicolai
Copy link
Author

Can't you give it a pointer to a const char[] PROGMEM?
That content would always be a the location given by the pointer and thus only in flash once?

@Makuna
Copy link
Collaborator

Makuna commented Jul 24, 2015

@mplus a PGM_P is a const char[] PROGMEM.

@renzenicolai
Copy link
Author

ah, okay

But, how would it then be possible to cause duplication when you are using a pointer?
("If the compiler doesn't do string duplication removal, and you call send_P is many locations, those can add up quickly.")

@martinayotte
Copy link
Contributor

@Makuna, Great !
So, you're quicker than me (I didn't started yet, so I leave you the work :-) )

@Makuna
Copy link
Collaborator

Makuna commented Jul 26, 2015

@mplus pointer uses are not commonly used by Arduino AVR developers, so you may see code where the same literal string is used like...
'''
Serial.print (F ("dup"));

...

Serial.print (F ("dup"));
'''
In this case, the compiler isn't smart enough with esp8266 to pool these, but with the AVR compiler will pool them, this difference is why this issue is raised.

@renzenicolai
Copy link
Author

I tried using the send_P function but it still causes crashes.

server.on ("/style.css", { Serial.println("CSS"); server.send_P( 200, "text/css", DATA_css ); } );

const char DATA_css[] PROGMEM = R"=====(
A LOT OF CSS HERE
)=====";

It crashes with the following message:

ets Jan 8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld

@Makuna
Copy link
Collaborator

Makuna commented Aug 22, 2015

@rnplus the content type is also progmem string, but you are not passing one.

please provide the smallest sample sketch that demonstrates your problem and I will look into it.

@renzenicolai
Copy link
Author

const char MIME_png[] PROGMEM = "image/png";
const char DATA_logo[] PROGMEM = { //PNG
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, //Logo
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x29,
0x08, 0x03, 0x00, 0x00, 0x00, 0x40, 0xf0, 0x8a, 0xdb, 0x00, 0x00, 0x00,
0x03, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0xdb, 0xe1, 0x4f, 0xe0,
0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0x00,
0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xcc, 0x00,
0x00, 0xff, 0x00, 0x33, 0x00, 0x00, 0x33, 0x33, 0x00, 0x33, 0x66, 0x00,
0x33, 0x99, 0x00, 0x33, 0xcc, 0x00, 0x33, 0xff, 0x00, 0x66, 0x00, 0x00,
0x66, 0x33, 0x00, 0x66, 0x66, 0x00, 0x66, 0x99, 0x00, 0x66, 0xcc, 0x00,
0x66, 0xff, 0x00, 0x99, 0x00, 0x00, 0x99, 0x33, 0x00, 0x99, 0x66, 0x00,
0x99, 0x99, 0x00, 0x99, 0xcc, 0x00, 0x99, 0xff, 0x00, 0xcc, 0x00, 0x00,
0xcc, 0x33, 0x00, 0xcc, 0x66, 0x00, 0xcc, 0x99, 0x00, 0xcc, 0xcc, 0x00,
0xcc, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x33, 0x00, 0xff, 0x66, 0x00,
0xff, 0x99, 0x00, 0xff, 0xcc, 0x00, 0xff, 0xff, 0x33, 0x00, 0x00, 0x33,
0x00, 0x33, 0x33, 0x00, 0x66, 0x33, 0x00, 0x99, 0x33, 0x00, 0xcc, 0x33,
0x00, 0xff, 0x33, 0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x66, 0x33,
0x33, 0x99, 0x33, 0x33, 0xcc, 0x33, 0x33, 0xff, 0x33, 0x66, 0x00, 0x33,
0x66, 0x33, 0x33, 0x66, 0x66, 0x33, 0x66, 0x99, 0x33, 0x66, 0xcc, 0x33,
0x66, 0xff, 0x33, 0x99, 0x00, 0x33, 0x99, 0x33, 0x33, 0x99, 0x66, 0x33,
0x99, 0x99, 0x33, 0x99, 0xcc, 0x33, 0x99, 0xff, 0x33, 0xcc, 0x00, 0x33,
0xcc, 0x33, 0x33, 0xcc, 0x66, 0x33, 0xcc, 0x99, 0x33, 0xcc, 0xcc, 0x33,
0xcc, 0xff, 0x33, 0xff, 0x00, 0x33, 0xff, 0x33, 0x33, 0xff, 0x66, 0x33,
0xff, 0x99, 0x33, 0xff, 0xcc, 0x33, 0xff, 0xff, 0x66, 0x00, 0x00, 0x66,
0x00, 0x33, 0x66, 0x00, 0x66, 0x66, 0x00, 0x99, 0x66, 0x00, 0xcc, 0x66,
0x00, 0xff, 0x66, 0x33, 0x00, 0x66, 0x33, 0x33, 0x66, 0x33, 0x66, 0x66,
0x33, 0x99, 0x66, 0x33, 0xcc, 0x66, 0x33, 0xff, 0x66, 0x66, 0x00, 0x66,
0x66, 0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x99, 0x66, 0x66, 0xcc, 0x66,
0x66, 0xff, 0x66, 0x99, 0x00, 0x66, 0x99, 0x33, 0x66, 0x99, 0x66, 0x66,
0x99, 0x99, 0x66, 0x99, 0xcc, 0x66, 0x99, 0xff, 0x66, 0xcc, 0x00, 0x66,
0xcc, 0x33, 0x66, 0xcc, 0x66, 0x66, 0xcc, 0x99, 0x66, 0xcc, 0xcc, 0x66,
0xcc, 0xff, 0x66, 0xff, 0x00, 0x66, 0xff, 0x33, 0x66, 0xff, 0x66, 0x66,
0xff, 0x99, 0x66, 0xff, 0xcc, 0x66, 0xff, 0xff, 0x99, 0x00, 0x00, 0x99,
0x00, 0x33, 0x99, 0x00, 0x66, 0x99, 0x00, 0x99, 0x99, 0x00, 0xcc, 0x99,
0x00, 0xff, 0x99, 0x33, 0x00, 0x99, 0x33, 0x33, 0x99, 0x33, 0x66, 0x99,
0x33, 0x99, 0x99, 0x33, 0xcc, 0x99, 0x33, 0xff, 0x99, 0x66, 0x00, 0x99,
0x66, 0x33, 0x99, 0x66, 0x66, 0x99, 0x66, 0x99, 0x99, 0x66, 0xcc, 0x99,
0x66, 0xff, 0x99, 0x99, 0x00, 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99,
0x99, 0x99, 0x99, 0x99, 0xcc, 0x99, 0x99, 0xff, 0x99, 0xcc, 0x00, 0x99,
0xcc, 0x33, 0x99, 0xcc, 0x66, 0x99, 0xcc, 0x99, 0x99, 0xcc, 0xcc, 0x99,
0xcc, 0xff, 0x99, 0xff, 0x00, 0x99, 0xff, 0x33, 0x99, 0xff, 0x66, 0x99,
0xff, 0x99, 0x99, 0xff, 0xcc, 0x99, 0xff, 0xff, 0xcc, 0x00, 0x00, 0xcc,
0x00, 0x33, 0xcc, 0x00, 0x66, 0xcc, 0x00, 0x99, 0xcc, 0x00, 0xcc, 0xcc,
0x00, 0xff, 0xcc, 0x33, 0x00, 0xcc, 0x33, 0x33, 0xcc, 0x33, 0x66, 0xcc,
0x33, 0x99, 0xcc, 0x33, 0xcc, 0xcc, 0x33, 0xff, 0xcc, 0x66, 0x00, 0xcc,
0x66, 0x33, 0xcc, 0x66, 0x66, 0xcc, 0x66, 0x99, 0xcc, 0x66, 0xcc, 0xcc,
0x66, 0xff, 0xcc, 0x99, 0x00, 0xcc, 0x99, 0x33, 0xcc, 0x99, 0x66, 0xcc,
0x99, 0x99, 0xcc, 0x99, 0xcc, 0xcc, 0x99, 0xff, 0xcc, 0xcc, 0x00, 0xcc,
0xcc, 0x33, 0xcc, 0xcc, 0x66, 0xcc, 0xcc, 0x99, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0xff, 0xcc, 0xff, 0x00, 0xcc, 0xff, 0x33, 0xcc, 0xff, 0x66, 0xcc,
0xff, 0x99, 0xcc, 0xff, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
0x00, 0x33, 0xff, 0x00, 0x66, 0xff, 0x00, 0x99, 0xff, 0x00, 0xcc, 0xff,
0x00, 0xff, 0xff, 0x33, 0x00, 0xff, 0x33, 0x33, 0xff, 0x33, 0x66, 0xff,
0x33, 0x99, 0xff, 0x33, 0xcc, 0xff, 0x33, 0xff, 0xff, 0x66, 0x00, 0xff,
0x66, 0x33, 0xff, 0x66, 0x66, 0xff, 0x66, 0x99, 0xff, 0x66, 0xcc, 0xff,
0x66, 0xff, 0xff, 0x99, 0x00, 0xff, 0x99, 0x33, 0xff, 0x99, 0x66, 0xff,
0x99, 0x99, 0xff, 0x99, 0xcc, 0xff, 0x99, 0xff, 0xff, 0xcc, 0x00, 0xff,
0xcc, 0x33, 0xff, 0xcc, 0x66, 0xff, 0xcc, 0x99, 0xff, 0xcc, 0xcc, 0xff,
0xcc, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x33, 0xff, 0xff, 0x66, 0xff,
0xff, 0x99, 0xff, 0xff, 0xcc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x7a, 0x7c, 0x1d,
0x00, 0x00, 0x01, 0x00, 0x74, 0x52, 0x4e, 0x53, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0xc9, 0x99, 0x6a, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73,
0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0e, 0xc4, 0x01, 0x95, 0x2b, 0x0e,
0x1b, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66,
0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x67, 0x6e, 0x6f, 0x6d, 0x65, 0x2d,
0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0xef, 0x03,
0xbf, 0x3e, 0x00, 0x00, 0x01, 0x52, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89,
0x8d, 0xd5, 0xdd, 0xb5, 0x83, 0x20, 0x0c, 0x00, 0x60, 0x36, 0xf0, 0xc9,
0xb8, 0x07, 0xee, 0xc2, 0x3e, 0xec, 0xc3, 0x3e, 0x64, 0x9c, 0x6b, 0x40,
0x9a, 0x1f, 0x08, 0x5e, 0xce, 0xe9, 0x43, 0x21, 0x9f, 0x84, 0x90, 0xd6,
0x80, 0xde, 0x00, 0x6f, 0x21, 0xb8, 0xe2, 0xf2, 0x8c, 0x47, 0xe0, 0xba,
0x3c, 0xe3, 0x10, 0x12, 0x9e, 0x59, 0x93, 0xb6, 0x87, 0x67, 0x96, 0xa4,
0x47, 0x7b, 0x66, 0x45, 0x46, 0xac, 0x63, 0x16, 0x84, 0x23, 0xd7, 0x66,
0x26, 0x32, 0x8e, 0x6a, 0x70, 0x7e, 0x12, 0xfd, 0xe4, 0x95, 0xb1, 0xc4,
0xe6, 0x42, 0xe6, 0xd8, 0x92, 0x29, 0xfb, 0x38, 0x9b, 0xb0, 0x17, 0xaf,
0xb9, 0x67, 0xd2, 0x2e, 0x1b, 0xee, 0x65, 0x85, 0x26, 0x43, 0xe4, 0xbc,
0x78, 0x2c, 0xee, 0xc1, 0x9a, 0x30, 0xfa, 0xc9, 0x15, 0x88, 0xb7, 0x36,
0x01, 0x8f, 0x76, 0xc0, 0x88, 0xeb, 0xb4, 0x30, 0x0d, 0x13, 0x99, 0x70,
0x20, 0xd8, 0x83, 0x3e, 0xa3, 0xd6, 0xc9, 0x04, 0xfa, 0x36, 0xd6, 0x61,
0xda, 0xa6, 0x76, 0xd2, 0x53, 0x79, 0x4d, 0x90, 0x61, 0x92, 0x2b, 0xd1,
0x2b, 0x84, 0x4c, 0xb8, 0x23, 0x0c, 0xf9, 0x89, 0x43, 0x16, 0x40, 0x91,
0xa8, 0x89, 0x16, 0x7c, 0xfc, 0x53, 0x24, 0x76, 0x28, 0xa2, 0x05, 0xcf,
0x87, 0x28, 0xb6, 0x54, 0x55, 0x9e, 0x44, 0x2a, 0xb5, 0x66, 0x22, 0xa2,
0xb4, 0x20, 0x1f, 0x36, 0x65, 0x95, 0x6b, 0x1b, 0xe9, 0x21, 0xad, 0x1f,
0x00, 0x4e, 0x50, 0xbf, 0x8d, 0x32, 0xc4, 0xcd, 0xa2, 0x64, 0x62, 0xd4,
0x30, 0xf7, 0xa2, 0x5f, 0x6a, 0xcf, 0x41, 0x5c, 0xe2, 0x23, 0xfa, 0x42,
0xa6, 0xb6, 0x8c, 0xa3, 0xcb, 0x0e, 0x5f, 0x3c, 0x53, 0x6d, 0x22, 0xd7,
0xd2, 0x9b, 0x3f, 0x9e, 0x00, 0xc0, 0xbd, 0x92, 0xc6, 0x41, 0x44, 0xa3,
0x58, 0x62, 0xc7, 0x6b, 0x64, 0x6b, 0xbd, 0xfb, 0x56, 0x8f, 0x0c, 0x03,
0x7c, 0x83, 0xcf, 0xc9, 0x73, 0xa2, 0x3a, 0x27, 0xef, 0x6f, 0x3c, 0xf5,
0xe3, 0x70, 0xb6, 0xf5, 0x1d, 0xd9, 0x7f, 0x59, 0xa4, 0x5f, 0x09, 0x86,
0x28, 0xf4, 0x49, 0x9b, 0xf7, 0x8b, 0x28, 0x1b, 0x8a, 0x8b, 0xc5, 0x2d,
0x11, 0x46, 0x8a, 0x2d, 0x69, 0xd9, 0x4c, 0x62, 0x4f, 0xa8, 0x6d, 0x8a,
0x15, 0x1f, 0xa4, 0x19, 0x23, 0xbe, 0x08, 0x19, 0x23, 0x3e, 0x09, 0x16,
0x55, 0xeb, 0x7f, 0x11, 0x2c, 0x46, 0xe0, 0x1f, 0x40, 0x6d, 0x94, 0xb4,
0x98, 0xd7, 0xe0, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
0xae, 0x42, 0x60, 0x82 };
...
server.on ("/logo.png", { server.send_P( 200, MIME_png, DATA_logo ); } );
...

Results in errors like this:

Exception (2):
epc1=0x3fff34e8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x3fff34e8 depc=0x00000000

ctx: sys
sp: 3ffffdc0 end: 3fffffb0 offset: 01a0

stack>>>
3fffff60: 00000000 40215a11 3ffed37c 3ffecfe0
3fffff70: 0156d8c7 60000600 40214d4a 3ffea230
3fffff80: 40215a56 3fffdab0 00000000 3fffdcb0
3fffff90: 3ffecff0 3fffdc20 3ffec8bc 40201c31
3fffffa0: 40000f49 3fffdab0 3fffdab0 40000f49
<<<stack<<<

ets Jan 8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld

@martinayotte
Copy link
Contributor

As discussed here http://www.esp8266.com/viewtopic.php?f=28&t=4688#p26962, I think the current ESP8266WebServer::sendContent_P() should be used for now only with text or html, since it doesn't have "size_t size" argument to tell the end of the content, it rely on NULL character at the end of the string. Maybe we will end up to add this "size_t size", this will allow binary too, like I did in my commit for WiFiClient::write_P() but still pending for merge.

@martinayotte
Copy link
Contributor

This commit waiting for PR merge should fix all the issues :
#753

@igrr
Copy link
Member

igrr commented Sep 30, 2015

Released in staging

@igrr igrr closed this as completed Sep 30, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants