Skip to content

[BUG] - TCBs and dynamic stacks leaked when scheduler is stopped #956

Closed
@cmorganBE

Description

@cmorganBE

When the scheduler is stopped, TCBs and dynamic stacks of running threads are not being freed. While ports, such as the posix port, clean up their resources, it appears as if the kernel itself is not freeing these resources when the scheduler is stopped.

TCBs are leaked from here, tasks.c: 1670

                /* Allocate space for the TCB. */
                /* MISRA Ref 11.5.1 [Malloc memory assignment] */
                /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
                /* coverity[misra_c_2012_rule_11_5_violation] */
                pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );  <----------------------------

Stacks are leaked from here, tasks.c:1662

            /* MISRA Ref 11.5.1 [Malloc memory assignment] */
            /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
            /* coverity[misra_c_2012_rule_11_5_violation] */
            pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );

            if( pxStack != NULL )
            {

@chinglee-iot with the merge of the posix changes I'm making use of them here for some tests. I'm not sure how it was missed before but it looks like we may have missed leaking task TCBs and dynamic task stacks.

A task's tcb appears to be freed in prvDeleteTCB() but its unclear how the posix port changes of cancelling and
deleting threads accomplish this.

Should vTaskStartScheduler() delete the TCBs and dynamic stacks for any running threads before returning? It feels like the port shouldn't really be doing this since TCBs/dynamic stacks are created and managed by FreeRTOS kernel proper.

Valgrind trace that got me started:

==1415351== HEAP SUMMARY:
==1415351==     in use at exit: 37,088 bytes in 4 blocks
==1415351==   total heap usage: 2,506 allocs, 2,502 frees, 491,264 bytes allocated
==1415351== 
==1415351== 160 bytes in 1 blocks are possibly lost in loss record 2 of 4
==1415351==    at 0x4845828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1415351==    by 0x1F0BB6: pvPortMalloc (heap_3.c:65) <---------------- this is a TCB
==1415351==    by 0x1EB38D: prvCreateTask (tasks.c:1670)
==1415351==    by 0x1EB460: xTaskCreate (tasks.c:1722)
==1415351==    by 0x1E6405: WaterTemperatureSim::Enable() (WaterTemperatureSim.h:51)
==1415351==    by 0x1E59D1: WaterTemperatureSimTest(void*) (test_WaterTemperatureSim.cpp:23)
==1415351==    by 0x1F1442: prvWaitForStart (port.c:507)
==1415351==    by 0x4C8CAD9: start_thread (pthread_create.c:444)
==1415351==    by 0x4D1D2E3: clone (clone.S:100)
==1415351== 
==1415351== 4,000 bytes in 1 blocks are possibly lost in loss record 3 of 4
==1415351==    at 0x4845828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1415351==    by 0x1F0BB6: pvPortMalloc (heap_3.c:65) <---------------- this is a task dynamic stack
==1415351==    by 0x1EB378: prvCreateTask (tasks.c:1662)
==1415351==    by 0x1EB460: xTaskCreate (tasks.c:1722)
==1415351==    by 0x1E6405: WaterTemperatureSim::Enable() (WaterTemperatureSim.h:51)
==1415351==    by 0x1E59D1: WaterTemperatureSimTest(void*) (test_WaterTemperatureSim.cpp:23)
==1415351==    by 0x1F1442: prvWaitForStart (port.c:507)
==1415351==    by 0x4C8CAD9: start_thread (pthread_create.c:444)
==1415351==    by 0x4D1D2E3: clone (clone.S:100)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions