lwmem error ?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

lwmem error ?

1,184 Views
m_bach
Contributor III

Hi There,

for some time now, I'm searching a bug which is really hard to find. Anyway, I reduced everything to a very small example code which crashes after several seconds.

The Scenario is described as:

- main1() and main2() are auto created tasks, started by MQX init

- both are just loops which are creating dynamic tasks dynamic1() and dynamic2()

- I'm using Kinetis K64-120 MHz, 256KB SRAM

- MQX Version is 4.2.0.2, so this should be fixed already: Bug Report: Memory pool corruption in _lwmem_alloc_align_internal 

Sometimes, _lwmem_test() reports Error 7 before everything hangs, which is MQX_CORRUPT_STORAGE_POOL_FREE_LIST, but more likely my system hangs before this is reported...

main.c and main.h is attached.

If I enabled MQX_USE_MEM instead of MQX_USE_LWMEM, the problem is gone, which makes me think there is an lwmem problem. On the other hand, the problem is also gone when enabling _time_delay(1) at the end of main2() and staying with lwmem.

This  seems very related to my Problem: stuck in _lwmem_get_next_block_internal() 

When the error condition occurs, _task_destroy_internal calls _lwmem_get_next_block_internal(), and than_lwmem_get_next_block_internal() crashes when trying to skip free blocks.

Thanks, 

  Martin

1 Reply

719 Views
m_bach
Contributor III

Hi there,

so I finally found the root cause. It's not lwmem, but task.c in conjunction with lwmem.

It's a little mind twisting, so I try to explain the patch attached:

When _task_destroy_internal() tries to apply it's garbage collection, it searches for all memory blocks using the own task ID.

Using _mem_get_next_block_internal(), _task_destroy_internal() tries to find mem blocks allocated by the own task, where _mem_free() hadn't been already applied by the task itself, as it should have.

When it finds blocks using our own task ID, but not belonging to our task, things become really bad.

And this can happen due to task prios and the way TASK IDs are getting re-used again.

When _task_destroy_internal()  marks the task ID as free to use again, there are up to three memory blocks left which are still marked as property to this task ID. When we now release TASK_CREATE_LWSEM, a high prio task might already be waiting for this semaphore to become ready. Hence it creates a task using that exact Task ID again. If this newly created dynamic task has a higher prio too, and terminates, it will detect all memory blocks of this task ID as garbage mem. But it falsely found and frees the three memory blocks of the old lower prio task.

I hope this is fixed in task.c with the patch attached.

cheers,

  Martin