GC issue? List.pool overwritten by allocated object

Steven Schveighoffer schveiguy at gmail.com
Mon May 12 21:29:10 UTC 2025


On Monday, 12 May 2025 at 18:22:16 UTC, Denis Feklushkin wrote:
> On Monday, 12 May 2025 at 15:40:01 UTC, Richard (Rikki) Andrew 
> Cattermole wrote:
>> On 13/05/2025 3:31 AM, Denis Feklushkin wrote:
>>> Perhaps all this is the result of an error somewhere else, 
>>> which results in this behavior. That is, if some my code (or 
>>> third party) corrupts something that affects to allocation? 
>>> But it seems that I do not do any hacks, any manipulations 
>>> with pointers, etc.
>>
>> This is pretty heavily used code in druntime, my immediate 
>> thought is what is your code doing to cause this (I didn't see 
>> anything obvious)?
>
> Yes, of course I understand perfectly well. And it seems to me 
> that I am not doing anything "reprehensible".

The "reprehensible" thing that almost always causes GC issues is 
use after free because you are interacting with C memory. I have 
not diagnosed the specific issue, but you are very much using 
some C libs to do complicated things.

I literally just fixed a bug at work that existed for 3 years 
because a GC object was being freed slightly early. Issue was -- 
we were using C memory that was owned by a GC object that was no 
longer referenced. GC runs -- destructor frees memory -- use 
after free.

Not saying this isn't some latent GC bug that has existed for a 
while. But the good news is that it's repeatable, so it should be 
possible to track down.

> Failure causes when code simply allocates by the "new" keyword, 
> which internally calls GC's smallAlloc(). Fails on different 
> points, depending on compilation options, compiled-in debug 
> facilities, sanitizers, etc. And if class what allocation 
> causes error manually moved into "heavy" by adding 64kB size 
> field just another class allocation causes same error.

Having errors very much points at the problem happening *before* 
`new` is called. If it's not always failing in the same spot, 
that sounds a lot like memory corruption. And very often the 
corruption happens long before the explosion.

> Maybe somewhere after destroy() I successfully write something 
> into destroyed object field and this corrupts internal GC data? 
> I'll try to remove everything destroy() calls right now

First thing I would rule out is C memory being used to refer to 
GC objects. Focus on places where C memory is allocated, 
especially with things like callbacks + data pointer.

Another cause, as I mentioned above, is using a GC object to 
manage C memory, and then forgetting the GC object but 
remembering the C memory.

-Steve


More information about the Digitalmars-d mailing list