www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 6874] New: heap corruption caused by std.array.insertInPlaceImpl or gc.gcx

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6874

           Summary: heap corruption caused by std.array.insertInPlaceImpl
                    or gc.gcx
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: druntime
        AssignedTo: nobody puremagic.com
        ReportedBy: mailme+d nilsb.dyndns.org



module test;
import std.array;

/* This should grow and shrink its -b- -n- times.
Instead, it pushes an array through the heap, nulling everything in its way,
because the involved functions keep thinking that the allocated block starts at
b.ptr while it is moving through the heap.
I can't say exactly which function is misbehaving, but I guess that one of
insertInPlace(), reallocNoSync(), findSize(), etc doesn't correctly handle
pointers that are not the base address of the allocated block. */
void berserk(size_t n) {
    int[] b = [0];
    foreach(i; 0 .. n) {
        version(length_is_fine) {
            b.length += 1;
        } else {
            b.insertInPlace(1, [0]);
        }
        b = b[1 .. $];
    }
}

void main() {
    int[] a = [1, 2, 3];
    berserk(5);
    assert(a == [1, 2, 3]); // fails
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 01 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6874




What happens is this: b.insertInPlaceImpl(...) does 
realloc(b.ptr, newLength * b[0].sizeof), assuming that realloc will allocate
enough space to safely write newLength values from b.ptr on.
But realloc does not guarantee that as it compares the requested size with
the result of gcx.findSize(b.ptr) to determine if it needs to allocate,
and gcx.findSize returns the size of the full block the pointer is in,
not of the space behind it. And b = [1 .. $]; moves b.ptr into the allocated
block.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 02 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6874


Nils <mailme+d nilsb.dyndns.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED



https://github.com/D-Programming-Language/phobos/commit/ae112b9dea12afa7bcba4c118f675ed8e8ff5ca2

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 18 2012