ftrias / TeensyThreads

MIT License
178 stars 26 forks source link

How to determine task stack overflow? #2

Closed smachin1000 closed 6 years ago

smachin1000 commented 6 years ago

Do you have any guidelines on how to best determine stack size for a task, or detect if stack overflow has occurred for a task?

ftrias commented 6 years ago

The thread provides two functions:

int getStackUsed(int id); int getStackRemaining(int id);

You can call these periodically to see if your stack is growing, which could indicate a problem.

smachin1000 commented 6 years ago

Thanks for the response. Any plans to implement something a bit more automated, such as what FreeRTOS does? http://www.freertos.org/Stacks-and-stack-overflow-checking.html

ftrias commented 6 years ago

For a proposed solution, see: https://forum.pjrc.com/threads/41504-Teensy-3-x-multithreading-library-first-release?p=151376&viewfull=1#post151376

smachin1000 commented 6 years ago

This looks like a good solution, I'll test it out this week.

smachin1000 commented 6 years ago

So once the code has entered stack_overflow_isr(), what are the restrictions on what it can do there? E.g. could I still use tasks.delay(x) if I wanted to flash an LED on and off to indicate we'd entered a stack overflow?

ftrias commented 6 years ago

The way the code is now, you cannot do anything involving the threading system. Threading is suspended in the isr(). It is actually are getting called within the context switch. Keep in mind that your stack just overflowed, so you'll corrupt your system more if you do anything on the stack like creating local variables or calling other functions. My assumption is that is overflowing your stack is probably a fatal error requiring a reboot or something drastic to recover.

So if you don't plan on returning from the isr(), then you can do almost anything that doesn't involve threading. Calling delay() and digitalWrite() should be fine.

If you want to continue running, I suggest using the isr() to just set a flag that's a global variable and then doing your task on the main thread (thread 0) whenever the flag is set.

In the future I suppose it's possible to have the overflow cause a thread switch and then run the isr() run on thread 0.

On Mon, Aug 28, 2017 at 11:23 AM, Sean Machin notifications@github.com wrote:

So once the code has entered stack_overflow_isr(), what are the restrictions on what it can do there? E.g. could I still use tasks.delay(x) if I wanted to flash an LED on and off to indicate we'd entered a stack overflow?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ftrias/TeensyThreads/issues/2#issuecomment-325385158, or mute the thread https://github.com/notifications/unsubscribe-auth/AGNroqFzr_ILPQxwoyEyQhtMooix8hTlks5scttcgaJpZM4Ogi1U .

smachin1000 commented 6 years ago

Current solution with the callback handler looks good for now. Is there anyway you could pass the thread ID into the overflow handler? (so we know which thread experienced the overflow)? I will close out the issue as resolved once we get an answer to the above.

ftrias commented 6 years ago

If call threads.id() you will get the current thread id that cause the fault.

smachin1000 commented 6 years ago

Ah yes, of course.