Stack smashing protect failure! in ESP32

65 Views Asked by At

When I want to stringify a json through ArduinoJson library, I face the error "Stack smashing protect failure!" and the esp32 reboots.

The decoded stack trace is as follow.

0x40083d51: panic_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c:408
0x4008cecd: esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c:137
0x400831d6: __stack_chk_fail at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/stack_check.c:35
0x400e35d5: makeStructJsonString(SensorMsg) at Handlers/TasksHandler.h:1206
0x400e395b: __networkHandler(void*) at src/RTOSHandler.cpp:757

The line of 1206 is String jsonString_;. The related task is made as follow:

xTaskCreatePinnedToCore(__networkHandler, "networkHandlerTask", 15 * KILOBYTES_C, NULL, 2, &networkHandler, 1);

I thought it is because of not having enough stack space. Therefore, I increased the size and even by increasing the size of stack up to 20KB, it still gives me the error and reboots.

I would appreciate any help.

1

There are 1 best solutions below

0
J_S On

While I haven't worked with ESP+FreeRTOS specifically, I did work with STM32+FreeRTOS and the methodology to find out the source of the problem should be the same.

Basically the idea is to put a data breakpoint (break on write) on the address just past the end of stack of the task that overflows. If I remember correctly, the way task stack overflow detection works in FreeRTOS is that actually reserves [your requested stack size + 4] bytes and places a 4-byte constant "pattern" (0xA5A5A5A5 for example) at those 4 additional bytes at the end. Stack overflow detection then simply checks whether that pattern is still there, as it should never change - unless you exceed the available stack area for the task. In your case - this is what __stack_chk likely does.

What I would do would be the following:

  • Find the address that __stack_chk checks for this task or calculate it myself - most FreeRTOS plugins that list tasks show task stack end address. In the worst case, you can examine the TCB for this task by hand.
  • Set a data write breakpoint for this address
  • Run the function that causes an issue
  • Your breakpoint should be hit exactly at the moment your stack overflows (e.g. when data is written to a large array), which should point you in the right direction.

Most often it's related to either calling a function with a large array placed on the stack, or calling a recursive function which by itself has an "average stack cost", but which becomes problematic when calls get nested deep enough (e.g. when recursively parsing a nested JSON).