Surprising behaviour of std.experimental.allocator
ag0aep6g
anonymous at example.com
Sat Dec 26 12:59:22 UTC 2020
On 24.12.20 17:12, Saurabh Das wrote:
> This causes a segfault when run with rdmd -gx:
>
[...]
>
> (Tested on DMD 2.094.2 and on https://run.dlang.io/is/p0FsOQ)
>
> If the "GC.collect()" line is commented out, it works somehow.
>
> Please help me understand why this is happening. This is a very reduced
> example of an issue I am facing.
Looks like a pretty nasty bug somewhere in std.experimental.allocator or
(less likely) the GC. Further reduced code:
----
import core.memory: GC;
import core.stdc.stdlib: malloc;
import std.experimental.allocator: allocatorObject;
import std.experimental.allocator.building_blocks.allocator_list:
AllocatorList;
import std.stdio: writeln;
import std.typecons: Ternary;
struct Mallocator
{
int x = 42;
void[] allocate(size_t n) nothrow @nogc
{
assert(n == 56); /* memory for bookkeeping, presumably */
void* p = malloc(n);
assert(p !is null);
debug writeln(&this, " malloced ", p);
return p[0 .. n];
}
Ternary owns(const void[] a) pure nothrow @nogc @safe
{
debug writeln(&this, " owns? ", a.ptr);
return a.ptr is null ? Ternary.no : Ternary.yes;
}
bool deallocateAll() pure nothrow @nogc @safe
{
assert(x == 42); /* fails; should pass */
return true;
}
enum alignment = 1;
}
struct List
{
AllocatorList!(n => Mallocator()) list;
void[] allocate(size_t n) nothrow
{
return list.allocate(n);
}
bool deallocate(void[] a) pure nothrow @nogc @safe { return false; }
enum alignment = 1;
}
void main()
{
auto alloc1 = allocatorObject(List());
() { ubyte[1000] stomp; } ();
GC.collect();
auto gca = new int;
}
----
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.
More information about the Digitalmars-d-learn
mailing list