pcTaskGetName returns strange task name

Hello everyone!

I’ve set an alarm message that the device sends if one of the RTOS tasks has a low stack value (<50). That way I receive JSON with pairs “pcTaskGetName”: “uxTaskGetStackHighWaterMark”. And I periodically receive these messages:
{
“type”: “rtosInfo”,
“WatchDog”: “105”
“C”: “0”,

}
But the original name of the task that “C” in the message is “Leds”. After sending this JSON the system goes into a hard fault exception.

I’m a rookie with FreeRTOS, so I got no idea what leads to this behavior. I can just assume that smth goes wrong with TCB, somehow it got overwritten.
Can anyone lead me to find out what’s going on?

Reading your message: I recommend that you first do the testing with more than enough stack space for every task. That will allow you to measure the actual stack usage.
And after that, if you want, you can decrease the stack sizes because you know how much is actually needed.

2 Likes

Hi, thank you for the quick response!

I got a lot of RAM on the board, so I gave tasks a lot of stack. But in this case for the “Leds” task I can not see anything that can lead to zero remaining stack. In fact this behavior takes place randomly even after days that my boards are running. Do you suggest that some other task stack overflow can lead to this system behavior, and I should focus on inspecting other tasks flows?

If a stack has already overflowed then potentially you have already corrupted a task control block. An overflow should not corrupt the name of the task that overflowed its stack, but could corrupt the stack of a neighboring task in memory.

Can you step through the code to see what happen when you create the JSON doc? That should show whether the name really is corrupt, or if there is another issue.

1 Like

Hello, thank you for the response!

The following line of code implements writing to the buffer that would be sent as alarm message:

if(Leds_Handle) n += sprintf(Buff + n, “”%s":"%d",", pcTaskGetName(Leds_Handle), uxTaskGetStackHighWaterMark(Leds_Handle));

Where “n” is the counter of characters to be sent.

Ok, so is that right that I should focus on the task that was created before the “Leds”? If so, then you can see in my first message the task named “WatchDog” got a stack of 105 and not overflowed. Could you please help me understand that?

Do you have any task with name “C”? If not, this most probably is memory corruption. What are the stack sizes for your tasks?

Also, please ensure to define configASSERT and enable Stack Overflow Checking.

Thanks.

1 Like

Hi Alex,

the line of code you posted looks extremly suspicious and error prone to me, first of all because of the double side effect on n, and then because sprintf() itself (as has been mentioned here a hundred times at least) is a stack guzzler. You might want to untangle this code a little. It might after all not be a problem of corrupted data structures but corrupted display.

1 Like

Hello, thank you for the response!

  • Do you have any task with name “C”?
    No.

  • If not, this most probably is memory corruption.
    Could you please be more specific, is it memory corruption caused by stack overflow of the task that was created before the “C”?

  • What are the stack sizes for your tasks?
    “C” (aka “Leds”) got (3 * configMINIMAL_STACK_SIZE) (configMINIMAL_STACK_SIZE = ((uint16_t)128). “WatchDog” task got (1 * configMINIMAL_STACK_SIZE).

Thanks for the recommended resources!

Hello and thank you for your recommendations!

Also could you please kindly advise on how mush action can I do inside vApplicationStackOverflowHook. Can delete all the tasks, increase the troubled task stack and then restart the scheduler?

One small point of procedure. I find that stack sizes rarely get defined right as multiples of configMINIMAL_STACK_SIZE, as that is a measure of base overhead for a simple function. You want to ADD to that the amount of memory that the task will need to do its real work.

1 Like

Hello!

Sorry for my ignorance, but what’s your (or maybe it’s common) definition of the simple function? Is there a reference function which stack frame equal to the configMINIMAL_STACK_SIZE?

Thanks for the response!

configMINIMAL_STACK_SIZE is approximately the amount of stack FreeRTOS itself needs to run a task.
I’m using vApplicationStackOverflowHook during development and in my case it ends up in a forever loop similar to the configASSERT macro. Goal is to avoid stack overflows later on in production code. However, when used in production code you should reset / restart the MCU resp. corrupted application (with minimal code). You know, anything can happen with a corrupted application.

1 Like

Hello, thank you for the information!

Simple answer, the Idle task gets the configMINIMAL_STACK_SIZE as I remember. so it uses a few functions, but not much.

1 Like

It will not be straight forward to terminate the task or increase the stack and restart the scheduler because at that point, you do not know how much memory has already been corrupted.

You should use it during development to catch stack overflows and adjust your stack sizes to ensure that it does not happen in production. The best best in production, as @hs2 mentioned, is to reset the MCU.

Thanks.

2 Likes