summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-06-26 23:21:04 -0700
committerKeith Packard <keithp@keithp.com>2012-06-26 23:21:04 -0700
commit8efac8eb99a9aabb45d9fbf742e4be91e4b331a5 (patch)
tree079ddc84f0c7e9a47fd71ee35436e6285726c246
parentebeac02a990da3fa6dd71487141d0bc6f78b42de (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.c24
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;