Thread overview
Help to find crash in simple stack type?
Jul 12, 2014
Gary Willoughby
Jul 12, 2014
anonymous
Jul 12, 2014
Rainer Schuetze
Jul 12, 2014
Rainer Schuetze
Jul 13, 2014
Gary Willoughby
July 12, 2014
I've created a simple stack type using calloc/free which seems to work nicely. Then instead of using C functions i've tried to implement the same type using the GC. However i'm experiencing a crash. I've been staring at this snippet for hours now any help would be appreciated. This is a simplified snippet showing the crash:

import std.stdio;
import core.memory;

class Stack(T)
{
	private T* _data;
	private T* _pointer;
	private immutable size_t _minimumSize;
	private size_t _size;
	private size_t _count;

	public this()
	{
		this._minimumSize = 32_000;
		this._size = this._minimumSize;
		this._data = cast(T*)GC.calloc(this._size, GC.BlkAttr.NO_MOVE);
		this._pointer = this._data;
		this._pointer--;
	}

	public void push(T value)
	{
		this._pointer++;

		if ((this._size / T.sizeof) < (this._count + 1))
		{
			this._size *= 2;
			writefln("realloc to %s bytes", this._size);
			this._data = cast(T*)GC.realloc(this._data, this._size, GC.BlkAttr.NO_MOVE);
			this._pointer = (this._data + this._count);
		}

		this._count++;
		*this._pointer = value;
	}
}

unittest
{
	auto stack = new Stack!(int);

	for (int x = 1; x <= 300_000 ; x++)
	{
		stack.push(x);
	}
}

It seems to crash when the loop iteration is at about 260,000 and i've no idea why. I'm using Ubuntu 64bit latest DMD.
July 12, 2014
No explanation or solution, but a reduction:

import core.memory;
void main()
{
     alias T = ubyte;

     enum size1 = 2_049; /* > 2_048 = 2^^11 */
     enum size2 = 1_048_577; /* > 1_048_576 = 2^^20 */

     T* _data;
     _data = cast(T*)GC.calloc(size1, GC.BlkAttr.NO_MOVE);
     _data = cast(T*)GC.realloc(_data, size2, GC.BlkAttr.NO_MOVE);

     T* _pointer = _data;
     foreach(i; 0 .. size2)
     {
         *_pointer = 0; /* segfault at i = 1_048_576 */
         _pointer++;
     }
}
July 12, 2014

On 12.07.2014 16:24, anonymous wrote:
> No explanation or solution, but a reduction:
>
> import core.memory;
> void main()
> {
>       alias T = ubyte;
>
>       enum size1 = 2_049; /* > 2_048 = 2^^11 */
>       enum size2 = 1_048_577; /* > 1_048_576 = 2^^20 */
>
>       T* _data;
>       _data = cast(T*)GC.calloc(size1, GC.BlkAttr.NO_MOVE);
>       _data = cast(T*)GC.realloc(_data, size2, GC.BlkAttr.NO_MOVE);
>
>       T* _pointer = _data;
>       foreach(i; 0 .. size2)
>       {
>           *_pointer = 0; /* segfault at i = 1_048_576 */
>           _pointer++;
>       }
> }

Thanks for the reduction. GC.realloc seems broken for reallocations to sizes larger than the current GC pool.

Please file a bug report.
July 12, 2014

On 12.07.2014 19:05, Rainer Schuetze wrote:
>
> Thanks for the reduction. GC.realloc seems broken for reallocations to
> sizes larger than the current GC pool.
>
> Please file a bug report.

Actually done that myself: https://issues.dlang.org/show_bug.cgi?id=13111
July 13, 2014
On Saturday, 12 July 2014 at 17:11:00 UTC, Rainer Schuetze wrote:
>
>
> On 12.07.2014 19:05, Rainer Schuetze wrote:
>>
>> Thanks for the reduction. GC.realloc seems broken for reallocations to
>> sizes larger than the current GC pool.
>>
>> Please file a bug report.
>
> Actually done that myself: https://issues.dlang.org/show_bug.cgi?id=13111

Thanks a lot guys!