Apart from defining the macros in config.h #define configUSE_STACK_OVERFLOW_HOOK 1 and #define configCHECK_FOR_STACK_OVERFLOW 0 and providing own hook function to handle the condition, is there anything else needed to be done in order to tell the kernel that user provides his own stack overflow hook in the user appli and over ride the kernel supplied hook ?
There is no kernel supplied hook and the application writer is supposed to supply the hook, if they want to enable stackoverflow checking. The possible values of configCHECK_FOR_STACK_OVERFLOW are 1 or 2 for enabling stackoverflow checking. This page contains all the details - FreeRTOS - stacks and stack overflow checking
ok, how to ensure that the user defined stack overflow hook is invoked , currently not getting invoked even if its supplied in the application and the macros necessary in freertosconfig.h are in place.
is there any other place wherein we need to configure or modify or enable something other than user application and config.h
is there any example listed in order to simuate stackoverflow and correspondingly activated the overflow hook
If you can still pass the compilation with configCHECK_FOR_STACK_OVERFLOW is set to 1 or 2, the hook function is successfully link to FreeRTOS kernel module.
I met few different scenarios when overflow happens. That overflow hook might not be invoked due to several reasons, like memory access exception.
One thing to remember is that Stack Overflow trapping is still an “After the fact” trap, and it is quite possible for an overflow to actually kill the program before the trap gets invoked. The only way to prevent that would be to be using hardware that traps at the moment the stack attempts to overflow. (Some processors have a stack bounds register, allowing the trapping at the moment of overflow, or a MPU might be able to catch an overflow).
ok, but will the overflow hook get invoked if application user enables the config macros and supply an implementation of his own overflow hook handler in an application source file
If you enable the overflow hook, then the overflow hook handler WILL get called IF the system gets to the point where it actually detects the overflow. Since, as I mentioned, FreeRTOS is using a post overflow detection method, it is possible for the program to “crash” before FreeRTOS gets a chance to detect it.
If you have a port that uses hardware stack checking registers, then you would need to see how the port defines its reporting, but it would seem reasonable for it to use the existing hooks.
If you have a port that uses an MPU to check, you will just get a protection exception like any other, and would need to look at what is happening to figure out what actually happened.
As @richard-damon explained, the stack overflow checking is more of a debugging aid and may not work in all the cases. Can you describe what are you trying to achieve? Are you trying to debug a stack overflow? When you say that the hook is not called, do you know that there is an stack overflow in your application? If yes, how did you verify that?
I want to define and use my own stackoverflow hook and simulate it so that
it can be verified the stack overflow hook gets activated whenever a stack overflow exception occurs. it reaches the handler function of overflow hook
May be if there is some sample application that simulates this behavior will be really helpful.
The target microcontroller is RH850 and kernel 10.4.1 is running on it.
You HAVE to define your own “hook” as that is what gets called if the overflow code detects an overflow.
Do you mean you want to define your own overflow CHECK?
You also mention a stack overflow EXCEPTION. Does your processor have an overflow exception, if so, then the port layer will need to keep it setup, and should put a call to the overflow hook in the exception vector.
It shouldn’t be hard to create a task to “simulate” an overflow by actually DOING an overflow, and if you statically allocate the task, you can put some extra space before the stack to even make it safe.
did the following steps to realise an overflow hook in application
-defined configCHECK_FOR_STACK_OVERFLOW to 2 and portSTACK_GROWTH to -1
implemented a handler for the overflow hook vApplicationStackOverflowHook expecting it will be activated once stack overflow occurs
use heap_4 as memory scheme
extern this handler in header as well
also defined INCLUDE_uxTaskGetStackHighWaterMark2
Created few tasks in Application and now need to simulate stack overflow
Question - how to simulate a stack overflow condition such that we know for sure this handler gets invoked when exception occur. This is just to test as a sample during development.
Create a task and have it use more stack than defined. Safest is to create the task statically, and give a stack buffer with additional room in front so the overflowing stack actually doesn’t overflow into addition memory.
One note, portSTACK_GROWTH should be defined in the porting layer, and configCHECH_FOR_STACK_OVERFLOW in FreeRTOSConfig.h by the application.
To “overflow” the stack, just allocate an array slightly too big for the stack you told it to use (but not so much to big that it overflows the buffer area you allocated with the static allocation).
Note, if you try to dynamically create the task, it is impossible to test the overflow “safely” as the overflow WILL access memory that is allocated for another purpose, so the best you can do it try and make the damage survivalble.
My comment about using xTaskCreateStatic is that the xTaskCreate function will give the task exactly as much stack as defined, and as such, overflowing it will by necessity involve exceeding the bounds of the memory allocated and possibly affecting unrelated objects with unknown effects.
Level 2 checking does add a small overflow detection zone, but you need to make your overflow very precise to just hit that and not exceed the actual space allocated.
That is why I suggest to actually do tests on the overflow checking to use a task statically created, so you can have the task “overflow” into space reserved for that overflow.
The following example shows what @richard-damon explained -
#define STACK_SIZE 64
StaticTask_t xTaskBuffer;
StackType_t xStack[ STACK_SIZE * 2 ];
void vTaskCode( void * pvParameters )
{
( void ) pvParameters;
for( ;; )
{
/* Call some functions here which will use stack. */
}
}
int main( void )
{
TaskHandle_t xHandle = NULL;
xHandle = xTaskCreateStatic( vTaskCode, /* Function that implements the task. */
"Task", /* Text name for the task. */
STACK_SIZE, /* Number of indexes in the xStack array. */
NULL, /* Parameter passed into the task. */
tskIDLE_PRIORITY,/* Priority at which the task is created. */
&( xStack[ STACK_SIZE ] ), /* Array to use as the task's stack. */
&xTaskBuffer ); /* Variable to hold the task's data structure. */
vTaskStartScheduler();
for( ;; )
{
}
}
In this example, we are creating the xStack array is of size 128. We supply only the second half of it to the task create API. Assuming the stack grows down, the stack overflow will grow into the lower memory address.
+----------------------------------+----------------------------------+
| | |
| Reserved for safe stack overflow | Used as task stack |
+---------------------------------------------------------------------+
I want to again emphasize that the stack overflow checking is more of a debugging aid and the hook may not get called in all the scenarios - where memory corruption leads to a fault even before the scheduler gets a chance to run.