Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 560 of 9367. Real-Time Operating Systems (RTOS)Free lesson

Implementing Stack Watermarking for Overflow Detection

Learners will configure memory patterns to detect stack exhaustion and identify the precise point of failure in memory-constrained RTOS tasks.

In this lesson, you will learn how to proactively detect task stack exhaustion by filling unused stack memory with a deterministic pattern, allowing you to identify the "high-water mark" of stack usage.

The Problem of Silent Failure

In memory-constrained RTOS environments, stack overflows are notoriously difficult to debug. When a task exceeds its allocated stack space, it typically overwrites adjacent memory—often corrupted TCB (Task Control Block) structures or other tasks' variables—leading to erratic system behavior or hard faults that occur long after the actual violation.

The Watermarking Technique

The strategy is simple: during task initialization, you fill the entire stack memory area with a specific, recognizable "magic number" pattern, such as 0xA5A5A5A5.

As a task executes and consumes stack space for local variables and nested function calls, it overwrites the magic pattern with actual data. If the task stays within its bounds, the bottom portion of the stack remains untouched and continues to hold the 0xA5 sequence.

To determine the high-water mark, the RTOS or a diagnostic monitor traverses the stack from the base address upward. The first instance where the pattern has been replaced by data marks the deepest point the stack has reached.

Implementation Concept

You can implement a simple stack-checking function that inspects this memory range:

#define STACK_MAGIC_PATTERN 0xA5A5A5A5

void check_stack_usage(uint32_t *stack_ptr, size_t stack_size) {
    size_t i = 0;
    // Walk from the beginning of the stack
    while (i < stack_size && stack_ptr[i] == STACK_MAGIC_PATTERN) {
        i++;
    }
    // 'i' now represents the number of untouched words
    size_t used_words = stack_size - i;
    printf("Stack usage: %u of %u words used\n", used_words, stack_size);
}

By calling this periodically or during a debug breakpoint, you can quantify how close a task is to a crash. If your monitor finds that the pattern has been completely overwritten, you have confirmed a stack overflow. This method provides a deterministic way to validate your stack size allocations without needing complex hardware memory protection units (MPU) for every scenario.

Key Takeaway: By pre-filling stack memory with a known magic pattern, you transform a hidden, catastrophic stack overflow into a measurable high-water mark that allows you to optimize memory allocation safely.