pavel-kirienko / o1heap

Constant-complexity deterministic memory allocator (heap) for hard real-time high-integrity embedded systems. There is very little activity because the project is finished and does not require further changes.
MIT License
245 stars 26 forks source link

Assertion error #12

Closed pepeRossRobotics closed 2 years ago

pepeRossRobotics commented 2 years ago

Hello, I am having the following error every now and then when using this library along with openCyphal. Is there any insight in what could be causing this?

I am running the code on a Raspberry Pi Compute modul 4 64b OS

The error happens when sending a service request. I have not found a pattern for when the error happens

o1heap/o1heap/o1heap.c:364: o1heapAllocate: Assertion `frag->header.size >= amount + (sizeof(void*) * 4U)' failed.
pavel-kirienko commented 2 years ago

Is there any insight in what could be causing this?

Heap corruption? Please try to log the values during the failure, and, most importantly, call o1heapDoInvariantsHold() before & after each access to the heap.

pepeRossRobotics commented 2 years ago

WHich values hould I log? I am working on top of a heavily modified version oof the Opencyphal Demos. This is how the heap allocation looks lik:

        static void* canardAllocate(CanardInstance* const ins, const size_t amount)
        {
            O1HeapInstance* const heap = ((State*) ins->user_reference)->heap;
            assert(o1heapDoInvariantsHold(heap));
            return o1heapAllocate(heap, amount);
        }

One modification I had to do to make the code compile alongside ROS2 was the way this bit of code:


            alignas(O1HEAP_ALIGNMENT) static uint8_t heap_arena[1024 * 16] = {0};
            state_global.heap = o1heapInit(heap_arena, sizeof(heap_arena));
            assert(NULL != state_global.heap);

as opposed to:

_Alignas(O1HEAP_ALIGNMENT) static uint8_t heap_arena[1024 * 16] = {0};
    state.heap                                                      = o1heapInit(heap_arena, sizeof(heap_arena));
    assert(NULL != state.heap);

Could it be that I just need to increase the size of the head and stack?

pavel-kirienko commented 2 years ago

Not sure about the stack. The size of the heap cannot be related to this issue. Please invoke o1heapDoInvariantsHold() both before and after each access to the heap (not only allocation). Use Valgrind. Ensure no concurrent access to the heap is taking place.

pepeRossRobotics commented 2 years ago

is this is what you mean by invoking it before and after interactingwith the heap?

            assert(o1heapDoInvariantsHold(heap));
            o1heapFree(heap, pointer);
            assert(o1heapDoInvariantsHold(heap));

After I increased the size of the heap and the pointer width to: #define O1HEAP_ALIGNMENT (sizeof(void*) * 8U) the error changed slightly to:

o1heap/o1heap/o1heap.c:397: o1heapFree: Assertionfrag->header.used' failed.`

I don't see how any concurrent access is taking place, but will look for it.

pavel-kirienko commented 2 years ago

is this is what you mean

yes

you're definitely dealing with memory corruption

pepeRossRobotics commented 2 years ago

Coming back to this, are there any Valgrind configuration that could ease debugging? I am following the post here: https://stackoverflow.com/questions/5134891/how-do-i-use-valgrind-to-find-memory-leaks

pavel-kirienko commented 2 years ago

Sorry, can't help with that directly. Just follow the general principles of fixing a memory corruption problem. Add some canaries to your heap-allocated blocks, too. I will close this issue as it is unlikely to be related to the library itself.

pepeRossRobotics commented 2 years ago

Perfect, will do, many thanks