Hi
I’m working on a project to explain some concepts about embedded systems and for one of the POC, I want to exhaust my stack.
I created a task using xTaskCreateStatic and used heap_1. Then I called a recursive code (because I want to exhaust memory). I used StackType_t of 104 uint32_t words and ulStackDepth as 50 uint32_t words for the call to xTaskCreateStatic.
Then I created some local variables (character arrays in my recursive task of size 100 each). My recursive code ran 100 times i.e. each call should have created an additional stack of 100 bytes (which clearly bypasses the stack I have allocated to this task).
2 problems:
Why didn’t my code give me a segmentation fault or at least should have called vApplicationStackOverflowHook?
Why is uxTaskGetStackHighWaterMark giving me a static value of 45 always?
I had expected uxTaskGetStackHighWaterMark to shrink on every recursive call or after the initialization of local variables in the task.
Please help. Let me know if code is needed for more details.
First of all, stack checking is not fool proof. If you simply allocate local variables without initializing them you will not overwrite the stack valid signature, and that validation would go unnoticed.
Second, stack validation is not real time. If you, say, overtrample the stack, therebye destroying isr’s memory, and then that isr interrupts the task, the code that does the signature checking (running as far as I remember at task switch time) will not have a chance to execute. In the above case, the ISR will fault before validation has a chance to run.
For that purpose, I created another task of the same priority, so that the 1st task could be switched out and the isr gets a chance to execute.
Moreover, I did initialize the variables. The recursive function is making use of them in every call.
Still, the same results. Where are my local variables getting memory if not on the task’s stack?
The Windows port creates a Windows thread for every FreeRTOS task - and Windows then uses the stack it allocated to that thread. In that case the stack allocated by FreeRTOS holds fixed size metadata and nothing else. Hence, FreeRTOS’s stack checking doesn’t work in the Windows port because it checks the wrong stack. I don’t know if the POSIX port works the same way, but could be an explanation if it does.
Hey @bluechip I wanted to reach out and see if this issue was related to the one you brought up on this forum post here? To me it seems that these are relevant questions since in both threads you were asking about variables on the stack and how that would impact your code’s path of execution.
Do you feel that this forum post has provided an answer for you in regards to this?
Glad to hear that your problem was solved! I’ve gone ahead and marked the link to your other post as the solution to your question.
Thanks so much for your patience with getting a solution.
Additionally thanks again for your contribution to FreeRTOS!
Hope you have a good day