App hangs, GC.collect() fixet it. Why?

Bastiaan Veelo Bastiaan at Veelo.net
Mon Sep 28 12:57:13 UTC 2020


On Friday, 5 June 2020 at 21:20:09 UTC, Steven Schveighoffer 
wrote:
> This kind of sounds like a codegen bug, a race condition, or 
> (worst case) memory corruption.

I think it must have been memory corruption: I had not realized 
that our old Pascal compiler aligns struct members on one byte 
boundaries, and also uses ubyte as the base type for enumerations 
(or ushort if required) instead of uint. When using memory mapped 
files this binary incompatibility likely caused the corruption.

But, after correcting that mistake, suddenly things broke that 
had been working for a long time. Having no idea what could be 
wrong this time, I spent quite some time dustmiting (thanks 
Vladimir!) and manually reducing the code. Voilà:


import std.stdio;
import core.memory;

struct Nothing
{
}

struct Info
{
align(1):
   ubyte u;
   Nothing*[2] arr;
}

Info* info;

void main()
{
   info = new Info;
   writeln("1");
   GC.collect();
   info.arr[0] = new Nothing;
   writeln("2");
   GC.collect();
   info.arr[1] = new Nothing;
   writeln("info.arr[0]  = ", info.arr[0]);
   writeln("info.arr[1]  = ", info.arr[1]);
   assert(info.arr[0] != info.arr[1], "Live object was 
collected!");
}


(The assert triggers on Windows, not on run.dlang.org.) 
Unfortunately for me, I cannot blame this on the compiler. It 
violates the requirements from the spec:

   "Do not misalign pointers if those pointers may point into the 
GC heap" (https://dlang.org/spec/garbage.html)

I am glad to have found the cause of the breakage finally, but it 
won't be easy to find a generic solution...

-Bastiaan.


More information about the Digitalmars-d-learn mailing list