espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.06k stars 7.31k forks source link

read nvs from usbcdc CORRUPTED #9825

Open Red-Owl opened 1 month ago

Red-Owl commented 1 month ago

Board

ESP32 wt32-s3-wrover (wt32sc01 plus)

Device Description

https://github.com/rpolitex/ArduinoNvs

Hardware Configuration

https://api.riot-os.org/group__boards__esp32s3__wt32__sc01__plus.html

Version

v3.0.1

IDE Name

visual studio code

Operating System

win11

Flash frequency

40mhz

PSRAM enabled

yes

Upload speed

115200

Description

return a data

Sketch

this function return correct nvs data
String gatto_get_serial(){
  String str = NVS.getString("serial");
  return str;
}

lv_obj_t * info_serial_label(lv_obj_t * cnt){
    INFO_SERIAL_LABEL = lv_label_create(cnt);
    lv_obj_set_pos(INFO_SERIAL_LABEL, 5, 80);
    String gg = lang._INFO_MODEL_SERIAL;
    gg += " " + gatto_get_serial();
    lv_label_set_text(INFO_SERIAL_LABEL, gg.c_str());
    return INFO_SERIAL_LABEL;
}

void usb_as_serial_read(){
    String data = USBCOM.readString();
    data.trim();  
    String com;
    String value;
    for (int i = 0; i <= data.length(); i++) {
      if(i == data.length()){
          com = data;
          value = "";
          break;
      }else if(data.charAt(i) == 61) {
          com = data.substring(0, i);
          value = data.substring(i+1, data.length());
          break;
      }
    }

      USBCOM.write("command->");
      USBCOM.write(com.c_str());
      USBCOM.write(" value:");
      USBCOM.write(value.c_str());
      USBCOM.write("<--");   

      if(com=="USBDATA"){
        if(value=="T"){
          serial_data_mode = true;
        }else if(value=="F"){
          serial_data_mode = false;
        }else{
          USBCOM.write("Invalid Option");  
        }
      }else
      if(com=="res"){
        gatto_enable_reserverd(value);
      }else
      if(com=="SESSION"){
        USBCOM.write(ENABLE_STRING.c_str());
      }else
      if(com=="md5"){
        char *md5str = hashMD5.md5(value.c_str());;
        USBCOM.write(md5str);
      }else
      if(com=="setserial"){
        String ch = value.c_str();
        int str_len = ch.length() + 1; 
        char char_array[str_len];
        ch.toCharArray(char_array, str_len);
        if(POLLO_ENABLE_MOD==true){
          gatto_set_serial(ch);
        //gatto_485_send(char_array);
        }
      }else
      if(com=="setmodel"){
        String ch = value.c_str();
        int str_len = ch.length() + 1; 
        char char_array[str_len];
        ch.toCharArray(char_array, str_len);
        if(POLLO_ENABLE_MOD==true){
          gatto_set_model(ch);
        // gatto_485_send(char_array);
      }
      }else
      if(com=="SERIAL"){
        String ch = gatto_get_serial();
        /* int str_len = ch.length() + 1; 
        char char_array[str_len];
        ch.toCharArray(char_array, str_len);
        //gatto_485_send(char_array); */
        USBCOM.write(ch.c_str());
      }else
      if(com=="ABOUT"){
        USBCOM.write(get_model_data().c_str());
      }

      /* if(com=="USBTO485"){
        if(value=="T"){
          usb_485_data_mode = true;
        }else if(value=="F"){
          usb_485_data_mode = false;
        }else{
          USBCOM.write("Invalid 485 Option");  
        }
      }else */ 
      if(com=="LIST"){
        USBCOM.write("display:");
        USBCOM.write(US_LIST);
        USBCOM.write("\nSERIAL:");
        String el = "ABOUT,USBDATA,INFO,HEAT,SERIAL,SESSION";
        USBCOM.write(el.c_str());
      }else if(com=="INFO"){
        USBCOM.write(get_esp32_chip_info().c_str());
      }else if(com=="HEAT"){
        USBCOM.write(get_esp32_chip_temperature().c_str());
      }else{
        char com_1[com.length() + 1]; 
        strcpy(com_1, com.c_str()); 
        char val_1[value.length() + 1]; 
        strcpy(val_1, value.c_str()); 
        gatto_command_set(com_1,val_1);
      }  

}  

static void usb_serial_callback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
  if(event_base == ARDUINO_USB_CDC_EVENTS){
    arduino_usb_cdc_event_data_t * data = (arduino_usb_cdc_event_data_t*)event_data;
    switch (event_id){
      case ARDUINO_USB_CDC_CONNECTED_EVENT:
        Serial.println("CDC CONNECTED");
        break;
      case ARDUINO_USB_CDC_DISCONNECTED_EVENT:
        Serial.println("CDC DISCONNECTED");
        break;
      case ARDUINO_USB_CDC_LINE_STATE_EVENT:
        Serial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts);
        break;
      case ARDUINO_USB_CDC_LINE_CODING_EVENT:
        Serial.printf("CDC LINE CODING: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity);
        break;
      case ARDUINO_USB_CDC_RX_EVENT:
        // USBCOM.printf("CDC RX [%u]:", data->rx.len);
        usb_as_serial_read();

        break;
       case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT:
        Serial.printf("CDC RX Overflow of %d bytes", data->rx_overflow.dropped_bytes);
        break;

      default:
        break;
    }
  }
}

Debug Message

CDC LINE CODING: bit_rate: 115200, data_bits: 8, stop_bits: 0, parity: 0
CDC CONNECTED
CDC LINE STATE: dtr: 1, rts: 1

Backtrace: 0xfffffffe:0x8037fe78 |<-CORRUPTED

ELF file SHA256: 975dcf75f59bcca3

Rebooting...

Other Steps to Reproduce

connect to usb, send SERIAL, crash

I have checked existing issues, online documentation and the Troubleshooting Guide

lbernstone commented 1 month ago

TL;DR. This looks a lot like a problem with your code. Make a minimal example. This is a pointer memory violation, so those strcpy are almost certainly the problem.

Red-Owl commented 1 month ago

i have disabled a final code strcpy,
this code create a crash:

String gatto_get_serial(){
  String str = NVS.getString("serial");
  return str;
}

if(com=="ass"){
        String ass = gatto_get_serial();  // call a function
        USBCOM.write(ass.c_str());  
      }

-------------this code not crash:-----------------------------


if(com=="ass"){
        String ass = NVS.getString("serial");   // this non crash
        USBCOM.write(ass.c_str());  
}
Red-Owl commented 1 month ago

On linux: Backtrace: 0xfffffffe:0x8037fa38 |<-CORRUPTED ELF file SHA256: e59f49159b024990

lbernstone commented 1 month ago

Pass pointers, not Strings. You are making lots of extra copies of the objects, and then attaching a local stack variable to your heap function result. In this case, keeping things as char (or even const char) all the way through will be much more efficient.

Red-Owl commented 1 month ago

Verion 4.4 idf (downgrade) this error is identical

Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception). Debug exception reason: Stack canary watchpoint triggered (arduino_usb_eve) Core 0 register dump: PC : 0x4038085b PS : 0x00060036 A0 : 0x8037f190 A1 : 0x3fcf1bc0
A2 : 0x3fc97220 A3 : 0xb33fffff A4 : 0x0000abab A5 : 0x00060023
A6 : 0x00060023 A7 : 0x0000cdcd A8 : 0xb33fffff A9 : 0xffffffff
A10 : 0x3fc971f4 A11 : 0x00000001 A12 : 0x00060021 A13 : 0x3fcf1c90
A14 : 0x02c97220 A15 : 0x00ffffff SAR : 0x00000002 EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x400557e1 LEND : 0x400557e5 LCOUNT : 0x00000000

Backtrace: 0x40380858:0x3fcf1bc0 0x4037f18d:0x3fcf1c00 0x4037d63c:0x3fcf1c30 0x4037d632:0xa5a5a5a5 |<-CORRUPTED

ELF file SHA256: d0c258a0e48ea1a6 Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception). Debug exception reason: Stack canary watchpoint triggered (arduino_usb_eve) Core 0 register dump: PC : 0x4038085b PS : 0x00060036 A0 : 0x8037f190 A1 : 0x3fcf1bc0
A2 : 0x3fc97220 A3 : 0xb33fffff A4 : 0x0000abab A5 : 0x00060023
A6 : 0x00060023 A7 : 0x0000cdcd A8 : 0xb33fffff A9 : 0xffffffff
A10 : 0x3fc971f4 A11 : 0x00000001 A12 : 0x00060021 A13 : 0x3fcf1c90
A14 : 0x02c97220 A15 : 0x00ffffff SAR : 0x00000002 EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x400557e1 LEND : 0x400557e5 LCOUNT : 0x00000000

Backtrace: 0x40380858:0x3fcf1bc0 0x4037f18d:0x3fcf1c00 0x4037d63c:0x3fcf1c30 0x4037d632:0xa5a5a5a5 |<-CORRUPTED

Red-Owl commented 1 week ago

.... this is contenent of arduinoNvs.h

PLEASE update info to string.h #include wstring.h

class ArduinoNvs {
public:
  ArduinoNvs();

  bool    begin(String namespaceNvs = "storage");
  void    close();

  bool    eraseAll(bool forceCommit = true);
  bool    erase(String key, bool forceCommit = true);

  bool    setInt(String key, uint8_t value, bool forceCommit = true);
  bool    setInt(String key, int16_t value, bool forceCommit = true);
  bool    setInt(String key, uint16_t value, bool forceCommit = true);
  bool    setInt(String key, int32_t value, bool forceCommit = true);
  .....