GC.realloc() fails to initialize some part of the memory
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Jul 16 17:44:19 PDT 2014
Here is an interesting case related to an undocumented feature of
GC.realloc(). Although I think there is a bug, I don't want to create a
bug report yet because the feature is not even documented. :)
First, here is its most recent definition from druntime/src/gc/gc.d:
void *realloc(void *p, size_t size, uint bits = 0, size_t
*alloc_size = null, const TypeInfo ti = null) nothrow
{
size_t localAllocSize = void;
auto oldp = p;
if(alloc_size is null) alloc_size = &localAllocSize;
// Since a finalizer could launch a new thread, we always need
to lock
// when collecting. The safest way to do this is to simply
always lock
// when allocating.
{
gcLock.lock();
p = reallocNoSync(p, size, bits, *alloc_size, ti);
gcLock.unlock();
}
if (p !is oldp && !(bits & BlkAttr.NO_SCAN))
{
memset(p + size, 0, *alloc_size - size);
}
return p;
}
As can be seen by that memset, it conditionally clears the newly
extended part of the memory area. (This is a bonus feature of Phobos
over C's standard library as the documentation of C's realloc() says
"newly allocated memory will be uninitialized".) However, memset() above
starts from 'p + size' where 'size' is the newly requested size. As a
result, the area between the old size and the new size are left
uninitialized.
The question is especially interesting and easier to demonstrate when
'p' is null because in that case although GC.realloc() tries to work
like GC.calloc(), it actually ends up working like GC.malloc().
The output of the following program demonstrates that the initial part
of the allocated memory is uninitialized. (I've gotten paranoid and
removed the output of running it on my computer; there could be credit
card numbers in there. :p)
import std.stdio;
import core.memory;
void main()
{
const length = 20;
auto p = GC.realloc(null, length);
writefln("%2s: %(%02x %)", length, p[0 .. length]);
}
Ali
More information about the Digitalmars-d-learn
mailing list