堆栈粉碎保护失败!在 ESP32

问题描述 投票:0回答:1

当我想通过 ArduinoJson 库对 json 进行字符串化时,我遇到错误“堆栈粉碎保护失败!”然后 esp32 重新启动。

解码后的堆栈跟踪如下。

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

1206的线路是

String jsonString_;
。 相关任务如下:

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

我认为这是因为没有足够的堆栈空间。因此,我增加了大小,甚至将堆栈大小增加到 20KB,它仍然给我错误并重新启动。

我将不胜感激任何帮助。

json arduino esp32 freertos arduinojson
1个回答
0
投票

虽然我没有专门使用过 ESP+FreeRTOS,但我确实使用过 STM32+FreeRTOS,并且找出问题根源的方法应该是相同的。

基本上,这个想法是在溢出任务的堆栈末尾的地址上放置一个数据断点(写入时中断)。如果我没记错的话,任务堆栈溢出检测在 FreeRTOS 中的工作方式实际上是保留

[your requested stack size + 4]
字节,并在末尾的这 4 个附加字节处放置一个 4 字节常量“模式”(例如
0xA5A5A5A5
)。然后,堆栈溢出检测只是检查该模式是否仍然存在,因为它永远不会改变 - 除非超出任务的可用堆栈区域。在你的情况下 - 这就是
__stack_chk
可能会做的事情。

我会做以下事情:

  • 找到
    __stack_chk
    检查此任务的地址或自己计算 - 大多数列出任务的 FreeRTOS 插件都会显示任务堆栈结束地址。在最坏的情况下,您可以手动检查此任务的 TCB。
  • 为此地址设置数据写入断点
  • 运行导致问题的函数
  • 断点应该在堆栈溢出时准确命中(例如,当数据写入大型数组时),这应该为您指明正确的方向。

大多数情况下,它与调用一个在堆栈上放置大数组的函数有关,或者与调用一个本身具有“平均堆栈成本”的递归函数有关,但是当调用嵌套得足够深时(例如,当递归解析时)就会出现问题嵌套的 JSON)。

© www.soinside.com 2019 - 2024. All rights reserved.