Thread overview
I may have found a bug.
May 29, 2013
Jeremy DeHaan
May 29, 2013
deadalnix
May 29, 2013
Diggory
May 29, 2013
Maxim Fomin
May 29, 2013
Jeremy DeHaan
May 29, 2013
Maxim Fomin
May 29, 2013
Martin Nowak
May 29, 2013
Marco Leise
May 29, 2013
Hey guys,

I believe I found a bug with Associative Arrays, and I want to make a bug report, but I am not sure what severity to place this under, or perhaps I am doing something wrong.


Here is what happens: If a class has a static Associative Array member, calling remove in the destructor will cause a invalid memory operation error if it is during a GC cycle(or at least at the end of the program). If the object is manually destroyed I get no such error. Also, if the Associative Array isn't a static member of the class and instead is a module scope variable, the error doesn't appear anymore.

I made a minimal example to show what I mean.

module main;

import std.conv;
import std.stdio;

void main(string[] args)
{
   AssocArrayTest test1 = new AssocArrayTest();

   //destroy(test1);
}


class AssocArrayTest
{
    private static string[uint] ClassNames;
    private static uint ClassIDCounter = 0;

    private uint ID;
    this()
    {
        ID = ClassIDCounter++;
        ClassNames[ID] = "AssocArrayTest " ~ text(ID);
        writeln(ClassNames[ID]);
    }

    ~this()
    {
        ClassNames.remove(ID);
    }
}


Thoughts?
May 29, 2013
On Wednesday, 29 May 2013 at 07:32:42 UTC, Jeremy DeHaan wrote:
> Thoughts?

static variables are thread local. Are you sure the destructor run in the same thread as the constructor ?
May 29, 2013
On Wednesday, 29 May 2013 at 10:33:32 UTC, deadalnix wrote:
> On Wednesday, 29 May 2013 at 07:32:42 UTC, Jeremy DeHaan wrote:
>> Thoughts?
>
> static variables are thread local. Are you sure the destructor run in the same thread as the constructor ?

Either way "remove" should simply fail not give a memory error.
May 29, 2013
On Wednesday, 29 May 2013 at 10:33:32 UTC, deadalnix wrote:
> On Wednesday, 29 May 2013 at 07:32:42 UTC, Jeremy DeHaan wrote:
>> Thoughts?
>
> static variables are thread local. Are you sure the destructor run in the same thread as the constructor ?

Actually it fails because _aaDelX calls gc, and gc is not reenterable. It has nothing to do with static or thread locals.
May 29, 2013
On Wednesday, 29 May 2013 at 11:08:55 UTC, Maxim Fomin wrote:
> On Wednesday, 29 May 2013 at 10:33:32 UTC, deadalnix wrote:
>> On Wednesday, 29 May 2013 at 07:32:42 UTC, Jeremy DeHaan wrote:
>>> Thoughts?
>>
>> static variables are thread local. Are you sure the destructor run in the same thread as the constructor ?
>
> Actually it fails because _aaDelX calls gc, and gc is not reenterable. It has nothing to do with static or thread locals.

But if I declare the AA as a module scope variable,static or not, in a different module, then I no longer get the invalid memory exception. It runs just fine.
May 29, 2013
On 05/29/2013 01:08 PM, Maxim Fomin wrote:
> Actually it fails because _aaDelX calls gc, and gc is not reenterable.
> It has nothing to do with static or thread locals.
Right, you currently can't perform GC operations in a finalizer.
Removing an element of a hashtable may trigger an internal reorganization which in turn allocates memory.
May 29, 2013
On Wednesday, 29 May 2013 at 16:46:09 UTC, Jeremy DeHaan wrote:
> On Wednesday, 29 May 2013 at 11:08:55 UTC, Maxim Fomin wrote:
>> On Wednesday, 29 May 2013 at 10:33:32 UTC, deadalnix wrote:
>>> On Wednesday, 29 May 2013 at 07:32:42 UTC, Jeremy DeHaan wrote:
>>>> Thoughts?
>>>
>>> static variables are thread local. Are you sure the destructor run in the same thread as the constructor ?
>>
>> Actually it fails because _aaDelX calls gc, and gc is not reenterable. It has nothing to do with static or thread locals.
>
> But if I declare the AA as a module scope variable,static or not, in a different module, then I no longer get the invalid memory exception. It runs just fine.

Than AA memory deletion operation happened to be placed after calling finalizer. Order of finalizer calls is not specified, so relying in dtors on member objects which reference GC memory is asking for exception. Note, that I cannot reproduce your behavior (I still get an exception).
May 29, 2013
Am Wed, 29 May 2013 19:05:09 +0200
schrieb Martin Nowak <code@dawg.eu>:

> On 05/29/2013 01:08 PM, Maxim Fomin wrote:
> > Actually it fails because _aaDelX calls gc, and gc is not reenterable. It has nothing to do with static or thread locals.
> Right, you currently can't perform GC operations in a finalizer. Removing an element of a hashtable may trigger an internal reorganization which in turn allocates memory.

Can we haz @nogc attributes attached to all dtors behind the scenes?

-- 
Marco