yubox-node-org / AsyncTCPSock

Reimplementation of the API of me-no-dev/AsyncTCP using high-level BSD sockets
GNU Lesser General Public License v3.0
20 stars 10 forks source link

Crash on beginResponse with template processor #12

Closed zekageri closed 2 years ago

zekageri commented 2 years ago

Hi! I got the following crash

Current free heap: 151396
Current free heap: 150276
Cleaning up socket clients
Current free heap: 152696
I'm not crashing here. 7
I'm not crashing here. 8
I'm not crashing here. 9
Current free heap: 127572
I'm not crashing here. 1
I'm not crashing here. 2
I'm not crashing here. 4
I'm not crashing here. 5
abort() was called at PC 0x4017f4c7 on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x4008f57c:0x3ffdc100 0x4008f7f5:0x3ffdc120 0x4017f4c7:0x3ffdc140 0x4017f50e:0x3ffdc160 0x4017ebe7:0x3ffdc180 0x4017ef1e:0x3ffdc1a0 0x400f3f2e:0x3ffdc1c0 0x400f4321:0x3ffdc1f0 0x400f4521:0x3ffdc280 0x400f00da:0x3ffdc2d0 0x400f00fd:0x3ffdc2f0 0x40182f8e:0x3ffdc310 0x40183a05:0x3ffdc340 0x40182a41:0x3ffdc3a0 0x400907fa:0x3ffdc3f0
  #0  0x4008f57c:0x3ffdc100 in invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:715
  #1  0x4008f7f5:0x3ffdc120 in abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:715
  #2  0x4017f4c7:0x3ffdc140 in __cxxabiv1::__terminate(void (*)()) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112      
  #3  0x4017f50e:0x3ffdc160 in std::terminate() at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112
  #4  0x4017ebe7:0x3ffdc180 in __cxa_throw at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc:87
  #5  0x4017ef1e:0x3ffdc1a0 in operator new(unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_op.cc:54
  #6  0x400f3f2e:0x3ffdc1c0 in __gnu_cxx::new_allocator<unsigned char>::allocate(unsigned int, void const*) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
      (inlined by) std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned int) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/alloc_traits.h:360
      (inlined by) std::_Vector_base<unsigned char, std::allocator<unsigned char> 
>::_M_allocate(unsigned int) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/stl_vector.h:170
      (inlined by) void std::vector<unsigned char, std::allocator<unsigned char> >::_M_range_insert<char const*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > >, char const*, char const*, 
std::forward_iterator_tag) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/vector.tcc:659
  #7  0x400f4321:0x3ffdc1f0 in void std::vector<unsigned char, std::allocator<unsigned char> >::_M_insert_dispatch<char const*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > >, char const*, char const*, std::__false_type) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
      (inlined by) __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > > std::vector<unsigned char, std::allocator<unsigned char> >::insert<char const*, void>(__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, char const*, char const*) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/stl_vector.h:1099
      (inlined by) AsyncAbstractResponse::_fillBufferAndProcessTemplates(unsigned 
char*, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:461
  #8  0x400f4521:0x3ffdc280 in AsyncAbstractResponse::_ack(AsyncWebServerRequest*, unsigned int, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
  #9  0x400f00da:0x3ffdc2d0 in AsyncWebServerRequest::_onAck(unsigned int, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebRequest.cpp:814
  #10 0x400f00fd:0x3ffdc2f0 in std::_Function_handler<void (void*, AsyncClient*, unsigned int, unsigned int), AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*)::{lambda(void*, AsyncClient*, unsigned int, unsigned int)#3}>::_M_invoke(std::_Any_data const&, void*&&, AsyncClient*&&, unsigned int&&, AsyncClient*&&) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebRequest.cpp:814
      (inlined by) _M_invoke at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0/functional:1871
  #11 0x40182f8e:0x3ffdc310 in std::function<void (void*, AsyncClient*, unsigned int, unsigned int)>::operator()(void*, AsyncClient*, unsigned int, unsigned int) const at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
      (inlined by) AsyncClient::_notifyWrittenBuffers(std::deque<AsyncClient::notify_writebuf, std::allocator<AsyncClient::notify_writebuf> >&, int) at lib\AsyncTCPSock\src/AsyncTCP.cpp:840
  #12 0x40183a05:0x3ffdc340 in AsyncClient::_sockIsWriteable() at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
  #13 0x40182a41:0x3ffdc3a0 in _asynctcpsock_task(void*) at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
  #14 0x400907fa:0x3ffdc3f0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

Rebooting...

The handler function:

    // These variables are char* variables and allocated in external ram at boot. like this:
    /*
      char* configString;
      void allocateVariables(){
          configString= (char *) ps_malloc (configStringSize* sizeof (char));
      }
      void setup(){
          allocateVariables();
      }
    */
    inline char* mainPageTemplateProcessor(const String& var){
        size_t max = (ESP.getFreeHeap() / 3) & 0xFFE0;
        if( var == "LAN_OB" ){
            Serial.println("I'm not crashing here. 1");
            getLangFile();
            return currentLangFile;
        }else if(var == "CONF_D"){
            if(hasConfig){
                Serial.println("I'm not crashing here. 2");
                if( max >= strlen(configString) ){
                    return (configString);
                }else{
                    return 0;
                }
            }
        }else if( var == "USR_D"){
            if(isThereUserFile){
                Serial.println("I'm not crashing here. 3");
                if( max >= strlen(usersString) ){
                    return (usersString);
                }else{
                    return 0;
                }
            }
        }else if( var == "HWCONF_D" ){
            Serial.println("I'm not crashing here. 4");
            if( max >= strlen(hwConfigString) ){
                return (hwConfigString);
            }else{
                return 0;
            }
        }else if( var == "USER_ZONES" ){
            if(hasZones){
                Serial.println("I'm not crashing here. 5");
                if( max >= strlen(zonesBuffer) ){
                    return zonesBuffer;
                }else{
                    return 0;
                }
                Serial.println("I'm not crashing here. 6");
            }
        }
        return 0;
    }

    void unlockSemaphoreOnResponseSent(){
        Serial.println("authentication response sent");
        xSemaphoreGive(userProgMutex);
    }

    static const inline void authenticateUser(AsyncWebServerRequest *request){
        AsyncWebServerResponse* response;
        xSemaphoreTake(userProgMutex, portMAX_DELAY); // <--- THIS SEMAPHORE PROTECTS THE VARIABLES THAT IS INSIDE THE PROCESSOR FUNCION 
        CLIENTLANG = "HU";
        boolean success = true;
        int userLvl     = -1;
        if (request->hasHeader("Cookie")) {
            AsyncWebHeader* allCookie = request->getHeader("Cookie");
            uint32_t userID = getCookie("userID", allCookie->value()).toInt();
            CLIENTLANG      = getCookie("lang", allCookie->value());
            if(CLIENTLANG == ""){CLIENTLANG  = "HU";}

            if( !userID ){
                success = false;
            }else if( userID != config.adminID ){
                userLvl = getUserLevel(userID);
            }else if(userID == config.adminID){
                userLvl = adminLvl;
            }
            if( userLvl != -1 && userLvl != 10 && isLoginExpired(userID) ){
                //Serial.println("Login expired.");
                success = false;
                userLvl = -1;
            }else if( userLvl == -1 ){
                success = false;
            }
        }else{
            success = false;
        }
        if(success){
            response = request->beginResponse(LITTLEFS, checkPath(homePath), "text/html", false, mainPageTemplateProcessor);
            Serial.println("I'm not crashing here. 7");
        }else{
            response = request->beginResponse(LITTLEFS, checkPath(loginPath), "text/html");
            response->addHeader("Content-Encoding", "gzip");
        }
        Serial.println("I'm not crashing here. 8");
        if(userLvl != -1){response->addHeader("Set-Cookie", "userLvl=" + String(userLvl));}
        request->onDisconnect(unlockSemaphoreOnResponseSent);
        Serial.println("I'm not crashing here. 9");
        request->send(response);
    }

As you can see i got 150k free heap right before the handler executes. The Serial.prints indicates that the crash is after the mainPageTemplateProcessor function returns the last variable. In 40% of the cases the webpage loading really fast, revealing all the variables from template processor and they are valid variables. If one of them is empty, i protect it with some boolean variables. The semaphore also takes care about the reads and writes from other functions. ( no other core uses these variables. everything runs on core 1 for me and a modbus communication on core 0 which has nothing to do with these variables )

What can cause the problem? Thank you in advance.

avillacis commented 2 years ago

Possibly relevant: the AsyncWebServerRequest::beginResponse() method that receives the template processor callback expects a callback method signature of the form:

typedef std::function<String(const String&)> AwsTemplateProcessor;

Your method has this signature instead: char* mainPageTemplateProcessor (const String &). Let's just hope the std::function template is smart enough to recognize the return type of the actual function and attempt to cast the char* to String, otherwise bad things might happen.

Additionally, your mainPageTemplateProcessor function has several paths by which it returns (char *)0, which the architecture probably interprets as NULL. From what I examined in the WString.cpp code, using the String object with a char* pointer that happens to be NULL will result in an internal NULL (not zero-length) buffer. Using the copy constructor of such a NULL String will propagate the NULL to the copied String object. With such an object, the WString::c_str() method will return NULL. And the template processing code contains a memcpy() with the source ptr returned from the WString::c_str() method without further validation...

Might be better to change the template processor signature, and make it return a constant empty string, not NULL, where appropiate, then try to trigger the issue again.

zekageri commented 2 years ago

Oh god. Thank you for the info. I did thought about that. I was about to make the function to return an error json string instead of 0. I will adjust my code.

Appreciate the help! I hope it will fix it

zekageri commented 2 years ago

Yeah it looks like the problem was the char return. I made the function back to String and cast every char to String before returning. It seems to work. I will test it now. Thank you for your help.

zekageri commented 2 years ago

Sorry i had to reopen this. It still can happen with this template processor:

inline String mainPageTemplateProcessor(const String& var){
      if( var == "LAN_OB" ){
          getLangFile();
          return String(currentLangFile);
      }else if(var == "CONF_D"){
          if(hasConfig){
              return String(configString);
          }
      }else if( var == "USR_D"){
          if(isThereUserFile){
              return String(usersString);
          }
      }else if( var == "USER_ZONES" ){
          if(hasZones){
              return String(zonesBuffer);
          }
      }
      return "";
 }

The thing is that all my buffers are char pointers, allocated in external ram. Should i copy it to a local String before returning it? Something like this:

inline String mainPageTemplateProcessor(const String& var){
      String buffer = "";
      if( var == "LAN_OB" ){
          getLangFile();
          // buffer = currentLangFile.toString();
          // buffer(currentLangFile);
          buffer = String(currentLangFile);
          //return String(currentLangFile);
      }else if(var == "CONF_D"){
          if(hasConfig){
              // buffer = configString.toString();
              // buffer(configString);
              buffer = String(configString);
              //return String(configString);
          }
      }else if( var == "USR_D"){
          if(isThereUserFile){
              // buffer = usersString.toString();
              // buffer(usersString);
              buffer = String(usersString);
              //return String(usersString);
          }
      }else if( var == "USER_ZONES" ){
          if(hasZones){
              // buffer = zonesBuffer.toString();
              // buffer(zonesBuffer);
              buffer = String(zonesBuffer);
              //return String(zonesBuffer);
          }
      }
      return buffer;
 }

Error dump again:

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x4008e2c6  PS      : 0x00060530  A0      : 0x800db64c  A1      
: 0x3ffde080
A2      : 0x3f80c385  A3      : 0x00000000  A4      : 0x0001869f  A5      
: 0x00000074
A6      : 0x00000001  A7      : 0x3ffda460  A8      : 0x00000001  A9      
: 0x00000000
A10     : 0x3ffde10c  A11     : 0x3ffde10c  A12     : 0x3ffde10c  A13     
: 0x3ffde100
A14     : 0x3ffde400  A15     : 0x3fa0e134  SAR     : 0x00000010  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x4008c9b8  LEND    : 0x4008c9d4  LCOUNT  
: 0x00000000

ELF file SHA256: 0000000000000000

Backtrace: 0x4008e2c6:0x3ffde080 0x400db649:0x3ffde0a0 0x401addd9:0x3ffde1a0 0x400f4518:0x3ffde1c0 0x400f47c5:0x3ffde250 0x400f037e:0x3ffde2a0 0x400f03a1:0x3ffde2c0 0x4018331e:0x3ffde2e0 0x40183d95:0x3ffde310 0x40182dd1:0x3ffde370 0x400907fa:0x3ffde3c0
  #0  0x4008e2c6:0x3ffde080 in strlcpy at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/string/../../../.././newlib/libc/string/strlcpy.c:55
  #1  0x400db649:0x3ffde0a0 in mainPageTemplateProcessor(String const&) at lib/ArduinoJson-6.x/src/ArduinoJson/Json/JsonDeserializer.hpp:58
      (inlined by) mainPageTemplateProcessor(String const&) at src/headers/authenticator.h:7
  #2  0x401addd9:0x3ffde1a0 in std::_Function_handler<String (String const&), String (*)(String const&)>::_M_invoke(std::_Any_data const&, String const&) at lib/ArduinoJson-6.x/src/ArduinoJson/Json/JsonDeserializer.hpp:58 
  #3  0x400f4518:0x3ffde1c0 in std::function<String (String const&)>::operator()(String const&) const at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
      (inlined by) AsyncAbstractResponse::_fillBufferAndProcessTemplates(unsigned char*, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:442
  #4  0x400f47c5:0x3ffde250 in AsyncAbstractResponse::_ack(AsyncWebServerRequest*, unsigned int, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
  #5  0x400f037e:0x3ffde2a0 in AsyncWebServerRequest::_onAck(unsigned int, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebRequest.cpp:814
  #6  0x400f03a1:0x3ffde2c0 in std::_Function_handler<void (void*, AsyncClient*, unsigned int, unsigned int), AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*)::{lambda(void*, AsyncClient*, unsigned int, unsigned int)#3}>::_M_invoke(std::_Any_data const&, void*&&, AsyncClient*&&, unsigned int&&, AsyncClient*&&) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebRequest.cpp:814
      (inlined by) _M_invoke at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0/functional:1871   
  #7  0x4018331e:0x3ffde2e0 in std::function<void (void*, AsyncClient*, unsigned int, unsigned int)>::operator()(void*, AsyncClient*, unsigned int, 
unsigned int) const at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
      (inlined by) AsyncClient::_notifyWrittenBuffers(std::deque<AsyncClient::notify_writebuf, std::allocator<AsyncClient::notify_writebuf> >&, int) at lib\AsyncTCPSock\src/AsyncTCP.cpp:840
  #8  0x40183d95:0x3ffde310 in AsyncClient::_sockIsWriteable() at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
  #9  0x40182dd1:0x3ffde370 in _asynctcpsock_task(void*) at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
  #10 0x400907fa:0x3ffde3c0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

Rebooting...
zekageri commented 2 years ago

With 4x page refresh it can generate this error:

authentication response sent
Current free heap: 132328
Current free heap: 140316
Current free heap: 109172
authentication response sent
Current free heap: 138896
abort() was called at PC 0x4017f903 on core 0

ELF file SHA256: 0000000000000000

Backtrace: 0x4008f57c:0x3ffdd2c0 0x4008f7f5:0x3ffdd2e0 0x4017f903:0x3ffdd300 0x4017f94a:0x3ffdd320 0x4017f023:0x3ffdd340 0x4017f35a:0x3ffdd360 0x400f4282:0x3ffdd380 0x400f4675:0x3ffdd3b0 0x400f4875:0x3ffdd440 0x400f042e:0x3ffdd490 0x400f0451:0x3ffdd4b0 0x401833ce:0x3ffdd4d0 0x40183e45:0x3ffdd500 0x40182e81:0x3ffdd560 0x400907fa:0x3ffdd5b0
  #0  0x4008f57c:0x3ffdd2c0 in invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:715
  #1  0x4008f7f5:0x3ffdd2e0 in abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c:715  
  #2  0x4017f903:0x3ffdd300 in __cxxabiv1::__terminate(void (*)()) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112
  #3  0x4017f94a:0x3ffdd320 in std::terminate() at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112
  #4  0x4017f023:0x3ffdd340 in __cxa_throw at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc:87
  #5  0x4017f35a:0x3ffdd360 in operator new(unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_op.cc:54      
  #6  0x400f4282:0x3ffdd380 in __gnu_cxx::new_allocator<unsigned char>::allocate(unsigned int, void const*) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
      (inlined by) std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned int) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/alloc_traits.h:360
      (inlined by) std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_allocate(unsigned int) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/stl_vector.h:170
      (inlined by) void std::vector<unsigned char, std::allocator<unsigned char> >::_M_range_insert<char const*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > >, char const*, char const*, std::forward_iterator_tag) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/vector.tcc:659
  #7  0x400f4675:0x3ffdd3b0 in void std::vector<unsigned char, std::allocator<unsigned char> >::_M_insert_dispatch<char const*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > >, char const*, char const*, std::__false_type) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
      (inlined by) __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > > std::vector<unsigned char, std::allocator<unsigned char> >::insert<char const*, void>(__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, char const*, char const*) at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0\bits/stl_vector.h:1099
      (inlined by) AsyncAbstractResponse::_fillBufferAndProcessTemplates(unsigned char*, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:461
  #8  0x400f4875:0x3ffdd440 in AsyncAbstractResponse::_ack(AsyncWebServerRequest*, unsigned int, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebResponses.cpp:700
  #9  0x400f042e:0x3ffdd490 in AsyncWebServerRequest::_onAck(unsigned int, unsigned int) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebRequest.cpp:814
  #10 0x400f0451:0x3ffdd4b0 in std::_Function_handler<void (void*, AsyncClient*, unsigned int, unsigned int), AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*)::{lambda(void*, AsyncClient*, unsigned int, unsigned int)#3}>::_M_invoke(std::_Any_data const&, void*&&, AsyncClient*&&, unsigned int&&, AsyncClient*&&) at lib\ESPAsyncWebServer-yuboxfixes-0xFEEDC0DE64-cleanup\src/WebRequest.cpp:814
      (inlined by) _M_invoke at c:\users\pc\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0/functional:1871   
  #11 0x401833ce:0x3ffdd4d0 in std::function<void (void*, AsyncClient*, unsigned int, unsigned int)>::operator()(void*, AsyncClient*, unsigned int, 
unsigned int) const at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
      (inlined by) AsyncClient::_notifyWrittenBuffers(std::deque<AsyncClient::notify_writebuf, std::allocator<AsyncClient::notify_writebuf> >&, int) at lib\AsyncTCPSock\src/AsyncTCP.cpp:840
  #12 0x40183e45:0x3ffdd500 in AsyncClient::_sockIsWriteable() at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
  #13 0x40182e81:0x3ffdd560 in _asynctcpsock_task(void*) at lib\AsyncTCPSock\src/AsyncTCP.cpp:360
  #14 0x400907fa:0x3ffdd5b0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

Rebooting...

With this processor:

inline String mainPageTemplateProcessor(const String& var) {
    String buffer = "";
    if (var == "LAN_OB") {
        getLangFile();
        buffer = String(currentLangFile);
    } else if (var == "CONF_D") {
        if (hasConfig) {
            buffer = String(configString);
        }
    } else if (var == "USR_D") {
        if (isThereUserFile) {
            buffer = String(usersString);
        }
    } else if (var == "USER_ZONES") {
        if (hasZones) {
            buffer = String(zonesBuffer);
        }
    }
    return buffer;
}
zekageri commented 2 years ago

Ditched the template processor. Instead the webpage rules all the relevant data via websockets.