Either I'm confused or the gc is

donallen donaldcallen at gmail.com
Wed Oct 21 21:35:43 UTC 2020


On Wednesday, 21 October 2020 at 18:55:50 UTC, H. S. Teoh wrote:
> On Wed, Oct 21, 2020 at 04:24:41PM +0000, donallen via 
> Digitalmars-d wrote:
>> [...]
>
> Welcome aboard! ;-)
>
>
> [...]
>> [...]
>
> Without seeing the rest of your code, or a minimal (runnable) 
> failing test case, it's hard to say for certain what the 
> problem is.  But if I were to guess, it looks like the GC is 
> prematurely collecting your arrays, though I can't imagine why 
> it would if you still retain references to it.
>
> One potential gotcha, since you mention that this is being 
> ported from C, is that if you pass pointers to GC-allocated 
> objects to C code which stores it somewhere, you need to make 
> sure you retain a reference somewhere on the D side of things, 
> or else inform the GC of the reference using 
> core.memory.GC.addRoot.[1]  Otherwise, since the GC may not be 
> aware of where the C code stores the pointer, it may fail to 
> find it and wrongly believe that the object is dead, and 
> thereby collect it prematurely.

I am not passing pointers to GC-allocated objects to C code. The 
only C code involved here is libsqlite3 and there the pointers I 
pass to it are those I obtained from it.

>
> [1] See: https://dlang.org/library/core/memory/gc.add_root.html
>
> Another potential problem is if your C code (or C-style code 
> ported to D) obscures pointers, e.g., using the XOR trick to 
> implement a doubly-linked list with only a single pointer 
> field, the GC will not be able to discover the reference, and 
> thus may wrongly mark the referenced object as dead.

Nope.

>
> Another thing that stuck out to me while glancing over your 
> code snippet, is that the `children` array doesn't seem to be 
> stored anywhere; this means it will go out of scope at the end 
> of the scope and possibly be collected, unless you retain at 
> least one reference to an array element somewhere.  I can't 
> tell if this is important without knowing the rest of your 
> code, but it's something to look into.  (Though it puzzles me 
> why this would be a problem, since obviously your code still 
> has a reference to *something* in that array in order for the 
> verifier code to check it. But it's something to look into if 
> there are no other clues.)

As I understand it from the documentation, dynamic arrays are 
represented as fat pointers that contain the array size and a 
pointer to the actual data in the heap. I assume, though the 
documentation doesn't say, that the size/pointer structure is on 
the stack. If so, every one of the children arrays has a pointer 
to it on the stack as the descent through the tree proceeds and 
therefore should not be garbage collectible until a particular 
call to the tree walker (of which I've provided the last bit of 
code, which deals with descending into the child accounts) 
returns to its caller.

It does look to me like those arrays are being collected 
prematurely and incorrectly.


More information about the Digitalmars-d mailing list