Hello,
I’m playing around with a FreeRTOS app and I’ve come up with something that looks a bit strange, some head corruption, the sequence goes on something like this:
-
An application task with a priority higher than the priority of the timer task is running and is about to delete its RTOS primitives before terminating. One of these primitives is an event group.
-
An ISR runs and signals the event group using xEventGroupSetBitsFromISR(). That sends a message to the low-priority timer task, and that message contains a pointer to the event group object.
-
When the ISR exits, the application task with a priority higher than the priority of the timer task continues running. The task calls vEventGroupDelete() to delete the event group and then terminates itself.
-
The FreeRTOS timer task is scheduled to run. It picks up the message that’s asking it to signal the event flags object, but that object was deleted already in step 3. The signalling changes some state in the object, but that ends up stepping on some random part of the heap and corrupts the heap.
-
The application eventually crashes when allocating from the corrupted heap.
I think that vEventGroupDelete() does not say if you’re not allowed to delete the object from a task that has higher priority than the timer task if the object was recently signalled from an ISR. Does it makes sense that if the kernel implements the signalling operation via some deferred call, that deferred call would be canceled in the delete operation if the deferred call has not yet run?
I would like to understand this better.
Also, to avoid accessing memory that has been freed, should the message sent by xEventGroupSetBitsFromISR() to the timer task’s queue be somehow canceled by vEventGroupDelete() if the timer task hasn’t run yet, or should vEventGroupDelete() document some extra limitation regarding when you’re allowed to delete the Event Group object?
Kind regards,
Sergio.