On 26.12.20 13:59, ag0aep6g wrote:
Looks like a pretty nasty bug somewhere in std.experimental.allocator or (less likely) the GC. Further reduced code:

----
[...]
----

Apparently, something calls deallocateAll on a Mallocator instance after the memory of that instance has been recycled by the GC. Maybe allocatorObject or AllocatorList keep a reference to GC memory out of sight of the GC.

I've looked into it some more, and as far as I can tell this is what happens:

1) allocatorObject puts the AllocatorList instance into malloced memory.
2) The AllocatorList puts the Mallocator instance into GC memory, because its default BookkeepingAllocator is GCAllocator. 3) The GC recycles the memory of the Mallocator instance, because it's only reachable via the malloced AllocatorList instance and malloced memory isn't scanned by default.
4) Hell breaks loose because that recycled memory was not actually garbage.

I'm not so sure anymore if this qualifies as a bug in std.experimental.allocator. Maybe AllocatorList should be registering its GC allocations as roots?

As a solution/workaround, you can use NullAllocator for AllocatorList's BookkeepingAllocator:

----
import std.experimental.allocator.building_blocks.null_allocator :
    NullAllocator;
alias Alloc1 = FallbackAllocator!(
    AllocatorList!(n => Region!Mallocator(1024*1024), NullAllocator),
    Mallocator);
----

Reply via email to