为什么我会出现Debug异常原因:Stack canary watchpoint triggered (main)?

13

我正在使用esp-idf-v3.0编写esp32-wroom-32的程序。
我想添加日志,这些日志将保存在fatfs中。
添加了一些日志后,我遇到了以下问题:

21:54:21.306 -> Debug exception reason: Stack canary watchpoint triggered (main) 
21:54:21.306 -> Register dump:
21:54:21.306 -> PC      : 0x40089827  PS      : 0x00060b36  A0      : 0x40082179  A1      : 0x3ffd3860  
21:54:21.340 -> A2      : 0x3ff40000  A3      : 0x00000033  A4      : 0x00000033  A5      : 0x00000000  
21:54:21.340 -> A6      : 0x00000024  A7      : 0xff000000  A8      : 0xe37fc000  A9      : 0x0000007e  
21:54:21.340 -> A10     : 0x00000000  A11     : 0xffffffff  A12     : 0x00000004  A13     : 0x00000001  
21:54:21.340 -> A14     : 0x00000005  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x00000001  
21:54:21.340 -> EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffff6  

为什么主要发生这种情况?

1个回答

26

FreeRTOS任务堆栈深度

这很可能是由于您的FreeRTOS任务中发生了堆栈溢出。

增加堆栈深度

我会做的第一件事是为您的FreeRTOS任务增加堆栈深度。例如,如果您使用configMINIMAL_STACK_SIZE创建了任务,则堆栈大小可能只有768字节,这对许多常见需求来说不足够。

需要增加多少堆栈深度?

这并不容易回答,但在这种情况下,只需将其增加到不再发生堆栈溢出即可。如果您担心不必要地浪费内存,FreeRTOS 包含一种机制,可以让您知道任务已经接近堆栈溢出。

缓冲区和canaries

Canary只是一个标记,位于缓冲区末尾-定期检查。如果它从默认值更改,意味着程序试图写入缓冲区末尾之外-即发生了缓冲区溢出

通过更改配置中的两个选项(在Component Config -> FreeRTOS部分下)启用使用canaries检测ESP IDF中的堆栈溢出:

  • 'Check for stack overflow' -> '使用金丝雀字节进行检查'
  • 'Set a debug watchpoint as a stack overflow check' -> 启用

enter image description here

如果禁用第二个选项,当栈溢出时,您将得到一个Guru Meditation错误-一个LoadProhibited异常。 xTaskCreate()和堆栈深度
请注意,ESP IDF中的xTaskCreate()版本与原始FreeRTOS中的版本不同。在原始FreeRTOS中,堆栈深度为单位指定。在ESP IDF中,它字节为单位指定。这是一个非常重要的区别!

非常感谢,我尝试更改了我的任务堆栈大小,现在它可以正常工作了! - user2993539

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接