CORRUPT HEAP: Bad Tail error

GeorgeFlorian1
Posts: 93
Joined: Thu Jan 31, 2019 2:32 pm

CORRUPT HEAP: Bad Tail error

Postby GeorgeFlorian1 » Tue May 14, 2019 9:16 am

Hello !

I just got this error:

Code: Select all

CORRUPT HEAP: Bad tail at 0x3ffde428. Expected 0xbaad5678 got 0x20736563
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c", line 245, function: multi_heap_realloc
abort() was called at PC 0x400e7f9f on core 1

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x40089048:0x3ffdc700 0x400892c5:0x3ffdc720 0x400e7f9f:0x3ffdc740 0x400923b1:0x3ffdc770 0x40084914:0x3ffdc790 0x40084979:0x3ffdc7b0 0x40085e19:0x3ffdc7d0 0x4000bedd:0x3ffdc7f0 0x400e109a:0x3ffdc810 0x400e10fc:0x3ffdc830 0x400e129a:0x3ffdc850 0x400e1403:0x3ffdc870 0x400d323d:0x3ffdc890 0x400d32b2:0x3ffdc8c0 0x40179e79:0x3ffdc8e0 0x400dce9d:0x3ffdc900 0x400dd0e1:0x3ffdc990 0x400dbc3e:0x3ffdc9e0 0x400da762:0x3ffdca20 0x400db1fd:0x3ffdca60 0x400d2f71:0x3ffdcac0 0x400d2fd1:0x3ffdcb10 0x400dd587:0x3ffdcb30 0x400db3ef:0x3ffdcb70 0x400db495:0x3ffdcbb0 0x400db6ed:0x3ffdcc00 0x4013b4c1:0x3ffdcc20 0x4013b509:0x3ffdcc60 0x4013b822:0x3ffdcc80 0x4008eff5:0x3ffdccb0

Code: Select all

0x40089048: vTaskPriorityInherit at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/tasks.c line 4079
0x400892c5: xTimerCreateTimerTask at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/timers.c line 259
0x400e7f9f: _vfprintf_r at ../../../.././newlib/libc/stdio/vfprintf.c line 1405
0x40084914: esp_rom_spiflash_write_status at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spi_flash/spi_flash_rom_patch.c line 284
0x40084979: esp_rom_spiflash_unlock at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spi_flash/spi_flash_rom_patch.c line 70
0x40085e19: rtc_clk_bbpll_enable at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/soc/esp32/rtc_clk.c line 445
0x400e109a: _svfprintf_r at ../../../.././newlib/libc/stdio/vfprintf.c line 1063
0x400e10fc: _svfprintf_r at ../../../.././newlib/libc/stdio/vfprintf.c line 962
0x400e129a: _svfprintf_r at ../../../.././newlib/libc/stdio/vfprintf.c line 1046
0x400e1403: _svfprintf_r at ../../../.././newlib/libc/stdio/vfprintf.c line 1118
0x400dce9d: spiffs_object_truncate at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 1751
0x400dd0e1: spiffs_object_truncate at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 1844
0x400dbc3e: spiffs_cb_object_event at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 1134
0x400da762: SPIFFS_rename at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_hydrogen.c line 879
0x400db1fd: spiffs_obj_lu_find_entry_visitor at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 154
0x400dd587: spiffs_object_read at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 2044
0x400db3ef: spiffs_erase_block at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 244
0x400db495: spiffs_obj_lu_scan at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 361
0x400db6ed: spiffs_obj_lu_find_id_and_span at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/spiffs/spiffs/src/spiffs_nucleus.c line 537
My project relies heavily on ESPAsyncWebServer.

Code: Select all

server.on("/events_placeholder.html", HTTP_GET, [](AsyncWebServerRequest* request){              
        request->send(SPIFFS, "/events_placeholder.html", "text/html", false, processor);
      });
      server.on("/jquery-1.12.5.min.js", HTTP_GET, [](AsyncWebServerRequest* request){              
        request->send(SPIFFS, "/jquery-1.12.5.min.js", "text/javascript");
      });	
      server.on("/master.css", HTTP_GET, [](AsyncWebServerRequest *request) {              
        request->send(SPIFFS, "/master.css", "text/css");
      });
      server.on("/back-image.jpg", HTTP_GET, [](AsyncWebServerRequest *request) {
        request->send(SPIFFS, "/back-image.jpg", "image/jpeg");
      });
      server.on("/logo.png", HTTP_GET, [](AsyncWebServerRequest *request) {
        request->send(SPIFFS, "/logo.png", "image/png");
      });

      server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){              
        request->redirect("/home");
      });
      server.on("/home", HTTP_GET, [](AsyncWebServerRequest* request){
        if(userFlag) {
          if(!request->authenticate(value_login[0].c_str(), value_login[1].c_str()))
            return request->requestAuthentication(NULL,false);
          request->send(SPIFFS, "/indexSTA.html", "text/html", false, processor);
        } else {
          request->send(SPIFFS, "/indexSTA.html", "text/html", false, processor);
        }        
      });

      server.on("/advanced-settings", HTTP_POST, [](AsyncWebServerRequest * request){
        int params = request->params();
        String values_button = "";
        for(int i=0;i<params;i++){
          AsyncWebParameter* p = request->getParam(i);
          if(p->isPost()){
              logOutput((String)"POST[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");            
              values_button = p->value();            
            } else {
                logOutput((String)"GET[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");
              }
        } // for(int i=0;i<params;i++)
        values_button.trim();
        if(values_button == "IP-Settings") {
          request->redirect("/IP-Config");
        }   
      });

      server.on("/IP-Config", HTTP_GET, [](AsyncWebServerRequest *request){
        if(userFlag) {
          if(!request->authenticate(value_login[0].c_str(), value_login[1].c_str()))
            return request->requestAuthentication(NULL,false);            
          request->send(SPIFFS, "/AP_configPage.html", "text/html");
        } else {
          request->send(SPIFFS, "/AP_configPage.html", "text/html");
        }  
      });
      server.on("/dhcpIP", HTTP_GET, [](AsyncWebServerRequest *request){
        if(userFlag) {
          if(!request->authenticate(value_login[0].c_str(), value_login[1].c_str()))
            return request->requestAuthentication(NULL,false);            
          request->send(SPIFFS, "/dhcpIP.html", "text/html");
        } else {
          request->send(SPIFFS, "/dhcpIP.html", "text/html");
        }
      });
      server.on("/staticIP", HTTP_GET, [](AsyncWebServerRequest *request){
        if(userFlag) {
          if(!request->authenticate(value_login[0].c_str(), value_login[1].c_str()))
            return request->requestAuthentication(NULL,false);            
          request->send(SPIFFS, "/staticIP.html", "text/html");
        } else {
          request->send(SPIFFS, "/staticIP.html", "text/html");
        }
      });

      server.on("/home", HTTP_POST, [](AsyncWebServerRequest * request){
        int params = request->params();
        String urlCopy = "";
        for(int i=0;i<params;i++){
          AsyncWebParameter* p = request->getParam(i);
            if(p->isPost()){
              logOutput((String)"POST[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");
              if(p->name() == "getURL" && p->value() != NULL) urlCopy = p->value();
              if(p->name() == "getBrightness" && p->value() != NULL)  Brightness = p->value();
              if(p->name() == "getRefreshRate" && p->value() != NULL)  urlRefreshRate = p->value(); 
            } else {
                logOutput((String)"GET[" + p->name().c_str() + "]: " + p->value().c_str() + "\n"); 
              }
        } // for(int i=0;i<params;i++)
        
        if(urlCopy != NULL && urlCopy.length() != 0) {
          URL = urlCopy;
          File urlWrite = SPIFFS.open("/configFile.txt", "w");
          if(!urlWrite) logOutput((String)"ERROR_INSIDE_URL_POST ! Couldn't open file to write URL !");
          urlWrite.println(urlCopy);
          urlWrite.close();
          request->redirect("/home");
        } else {
          request->redirect("/home");
        }
      });

      server.on("/staticIP", HTTP_POST, [](AsyncWebServerRequest * request){      
          int params = request->params();
          String values_static[6];
          for(int i=0;i<params;i++){
            AsyncWebParameter* p = request->getParam(i);
            if(p->isPost()){
                logOutput((String)"POST[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");
                values_static[i] = p->value();            
              } else {
                  logOutput((String)"GET[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");
                }
          } // for(int i=0;i<params;i++)
          // logOutput((String)"Printing values from staticLogin POST: ");
          // for(int i = 0; i<6; i++) {
          //   logOutput(values[i]);
          //   }
          
          if(values_static[0] != NULL &&
            values_static[0].length() != 0 &&
            values_static[1] != NULL &&
            values_static[1].length() != 0 &&
            values_static[2] != NULL &&
            values_static[2].length() != 0 &&
            values_static[3] != NULL &&
            values_static[3].length() != 0 &&
            values_static[4] != NULL &&
            values_static[4].length() != 0 &&
            values_static[5] != NULL &&
            values_static[5].length() != 0) {
                File inputsWrite = SPIFFS.open("/inputs.txt", "w");
                if(!inputsWrite) logOutput((String)"ERROR_INSIDE_POST ! Couldn't open file to write Static IP credentials !"); 
                inputsWrite.println(values_static[0]);   // SSID
                inputsWrite.println(values_static[1]);   // Password
                inputsWrite.println(values_static[2]);   // Local IP
                inputsWrite.println(values_static[3]);   // Gateway
                inputsWrite.println(values_static[4]);   // Subnet
                inputsWrite.println(values_static[5]);   // DNS
                inputsWrite.close();
                logOutput("Configuration saved !");
                logOutput("Restarting in 5 seconds...");
                request->redirect("/home");
                // digitalWrite(LED, LOW);
                restartFlag = true;
          } else request->redirect("/staticIP");
          
          }); // server.on("/staticLogin", HTTP_POST, [](AsyncWebServerRequest * request)

      server.on("/dhcpIP", HTTP_POST, [](AsyncWebServerRequest * request){
        
        int params = request->params();
        String values_dhcp[2];
        for(int i=0;i<params;i++){
          AsyncWebParameter* p = request->getParam(i);
          if(p->isPost()){
              logOutput((String)"POST[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");            
              values_dhcp[i] = p->value();            
            } else {
                logOutput((String)"GET[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");
              }
        } // for(int i=0;i<params;i++)
        
        if(values_dhcp[0] != NULL && values_dhcp[0].length() != 0 &&
          values_dhcp[1] != NULL && values_dhcp[1].length() != 0) {
          File inputsWrite = SPIFFS.open("/inputs.txt", "w");
          if(!inputsWrite) logOutput((String)"ERROR_INSIDE_POST ! Couldn't open file to write DHCP IP credentials !");
          inputsWrite.println(values_dhcp[0]);  // SSID
          inputsWrite.println(values_dhcp[1]);  // Password
          inputsWrite.close();
          logOutput("Configuration saved !");
          logOutput("Restarting in 5 seconds...");
          request->redirect("/home");
          restartFlag = true;
        } else request->redirect("/dhcpIP");
      
      }); // server.on("/dhcpLogin", HTTP_POST, [](AsyncWebServerRequest * request)
        
      server.begin();
The error happened while I was on the web-pages and "testing" them: changing some input values, refreshing... trivial stuff.

ESP_Angus
Posts: 1812
Joined: Sun May 08, 2016 4:11 am

Re: CORRUPT HEAP: Bad Tail error

Postby ESP_Angus » Tue May 14, 2019 9:58 am

This is a symptom of a buffer overflow somewhere in the code. The word 0x20736563 has been written past whatever heap buffer was allocated (via malloc, calloc, new, etc) to hold that data. The "tail canary" feature of the heap allocator has picked this corruption up.

(0x20736563 == bytes 0x63, 0x65, 0x73, 0x20 == string "?AI " so that may give you some hint as to what buffer has overflowed.)

You can read all about IDF's heap corruption detection features here:
https://docs.espressif.com/projects/esp ... -detection

GeorgeFlorian1
Posts: 93
Joined: Thu Jan 31, 2019 2:32 pm

Re: CORRUPT HEAP: Bad Tail error

Postby GeorgeFlorian1 » Tue May 14, 2019 11:16 am

ESP_Angus wrote:
Tue May 14, 2019 9:58 am
This is a symptom of a buffer overflow somewhere in the code. The word 0x20736563 has been written past whatever heap buffer was allocated (via malloc, calloc, new, etc) to hold that data. The "tail canary" feature of the heap allocator has picked this corruption up.

(0x20736563 == bytes 0x63, 0x65, 0x73, 0x20 == string "?AI " so that may give you some hint as to what buffer has overflowed.)

You can read all about IDF's heap corruption detection features here:
https://docs.espressif.com/projects/esp ... -detection
Thank you for your answer !

This is actually a known issue with the ESPAsyncWebServer library.
me-no-dev responded to one of my post saying that he didn't manage to fix it.

Who is online

Users browsing this forum: No registered users and 10 guests