diff options
author | Keith Packard <keithp@keithp.com> | 2012-06-26 23:21:04 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2012-06-26 23:21:04 -0700 |
commit | 8efac8eb99a9aabb45d9fbf742e4be91e4b331a5 (patch) | |
tree | 079ddc84f0c7e9a47fd71ee35436e6285726c246 | |
parent | ebeac02a990da3fa6dd71487141d0bc6f78b42de (diff) |
altos: Add debugging code to check for stack overflow
Stack overflow often happens from interrupt handlers sitting on top of
a task stack. Check for this during ao_wakeup as that is often called
during interrupt processing.
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | src/core/ao_task.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 910f1587..4011a36e 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "ao.h" +#include <ao.h> #define AO_NO_TASK_INDEX 0xff @@ -28,6 +28,20 @@ __xdata struct ao_task *__data ao_cur_task; ao_arch_task_globals #endif +#define AO_CHECK_STACK 0 + +#if AO_CHECK_STACK +static uint8_t in_yield; + +static inline void ao_check_stack(void) { + uint8_t q; + if (!in_yield && ao_cur_task && &q < &ao_cur_task->stack[0]) + ao_panic(AO_PANIC_STACK); +} +#else +#define ao_check_stack() +#endif + void ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant { @@ -68,6 +82,9 @@ ao_yield(void) ao_arch_naked_define ao_arch_isr_stack(); +#if CHECK_STACK + in_yield = 1; +#endif /* Find a task to run. If there isn't any runnable task, * this loop will run forever, which is just fine */ @@ -97,6 +114,10 @@ ao_yield(void) ao_arch_naked_define } } } +#if CHECK_STACK + cli(); + in_yield = 0; +#endif ao_arch_restore_stack(); } @@ -117,6 +138,7 @@ ao_wakeup(__xdata void *wchan) { uint8_t i; + ao_check_stack(); for (i = 0; i < ao_num_tasks; i++) if (ao_tasks[i]->wchan == wchan) ao_tasks[i]->wchan = NULL; |