www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - I may have found a bug.

reply "Jeremy DeHaan" <dehaan.jeremiah gmail.com> writes:
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
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
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
parent Martin Nowak <code dawg.eu> writes:
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.

Removing an element of a hashtable may trigger an internal reorganization which in turn allocates memory.
May 29 2013
prev sibling next sibling parent "Diggory" <diggsey googlemail.com> writes:
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
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
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
prev sibling next sibling parent "Jeremy DeHaan" <dehaan.jeremiah gmail.com> writes:
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
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
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
prev sibling parent Marco Leise <Marco.Leise gmx.de> writes:
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.

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
May 29 2013