1

I am writing a program for esp32 on Arduino IDE. On some point of execution of code for File reading I am facing this exception,

Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask) 

However on reading few forums I found an answer of increasing the depth of the stack for your FreeRTOS task. My question is there any other way to handle this exception other than increasing stack size and avoid the program from crashing ?

4

The best way to handle this exception is to identify what's using so much space on the stack and rewrite your code to avoid it.

The three most common ways you'd use too much stack space are:

  1. large local variables - for instance, declaring a large array as a local variable inside a function, like:
#define VERY_LARGE_STRING_LENGTH 8000

void loop() {
  char my_very_large_string[VERY_LARGE_STRING_LENGTH];

  for(i = 0; i < VERY_LARGE_STRING_LENGTH; i++)
    my_very_large_string[i] = ' ';
}

Local variables are stored on the stack, so a large array of them will use up a lot of stack space.

  1. recursive functions - each time a function recurses it uses stack space. If it recurses deeply enough then it will trample the stack guard and cause this exception. For instance:
int count(i) {
  i--;

  if(i > 0) {
    Serial.println(count(i));
  }

  return i;
}

void loop() {
  count(8000);
}

Each time a function recurses, its return address and its arguments and local variables are all stored on the stack. If it recurses too many times it will use more storage than is allocated to the stack.

  1. mistakes in your code like wild pointers and buffer overruns
void loop() {
  char my_bad_string[10];
  char *wild_pointer;

  // buffer overrun
  for(i = 0; i < 8000; i++)
    my_bad_string[i] = ' ';

  // who knows where this will end up pointing
  wild_pointer += rand();
  wild_pointer = ' ';
}

when you overrun an array on the stack you'll probably overwrite other variables and corrupt their values. Do it enough and you'll hit the stack guard. Remember that C strings (char arrays and pointers) need n+1 characters to store a string of length n because they're terminated with an extra null '\0' character.

If you're using recursive functions, look at ways to limit the recursion or use tail recursion which the compiler may be able to optimize to avoid using excessive stack space.

If you're using large variables, think about why and rewrite your code to be able to use smaller variables. For instance, if you're reading a large file, try to process it a line at a time rather than reading the entire file into memory. If you're downloading large JSON from a web server, try using a streaming JSON parser rather than downloading the entire thing and then processing it.

A mistake in your code will be the hardest to figure out, given that it's a mistake. Be careful about pointers and memory allocation. Although memory is allocated from the heap and not the stack, if it's overwritten or reused after it's been freed using it as a pointer can still cause stack corruption. Also be careful to not return pointers to local variables inside functions:

int *do_not_do_this() {
  int this_will_not_work_the_way_you_hope = 0;

  return &this_will_not_work_the_way_you_hope;
}

can also lead to stack corruption as the space occupied by the variable will no longer be reserved for it and may be used by something else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.