GC issue? List.pool overwritten by allocated object
Denis Feklushkin
feklushkin.denis at gmail.com
Fri May 16 20:26:44 UTC 2025
On Friday, 16 May 2025 at 10:42:36 UTC, Denis Feklushkin wrote:
> On Wednesday, 14 May 2025 at 09:11:13 UTC, Denis Feklushkin
> wrote:
>
>> Okay, I think the question can be considered closed
>
>
> However, I am still on this issue! :(
I still think this is may be a druntime issue. And it's probably
not about TLS.
I discovered the [rr](https://github.com/rr-debugger/rr) tool
that allows quickly create and replay repeatable replays in the
gdb (its built-in system works very slowly). So now there's no
need to run gdb many times and carefully examine everything. `rr`
available in Debian, but that version doesn't work with my code -
some kind of tick counting error, seems because video driver
used), but self-compiled one works fine.
So, after playing and rewind few times I clearly see:
I made sure that malloc uses switched "arenas" as soon as threads
appear - this mechanism is built into glibc and enabled
automatically when second pthread created.
I also tried replacing `free(void*)` symbol with my own empty
stub to make sure that nothing was freed definitely and someone
didn't get the used piece again. It didn't help.
Vulkan library quite legitimately allocates some memory for its
needs, uses it, and this memory contains that memory piece where
the issue occurs. I don't know why Valgrind answered (evasively)
that this memory had not been allocated before.
Next, when executing on the D side, GC's pool of small
allocations (of size 32) is exhausted. And then some magic
happens in the gc.d code using recoverPool near
`SmallObjectPool.allocPage()`, which I do not fully understand.
(Obliviously, this is necessary to reuse the memory that was
previously allocated.)
As a result, a new `List` is formed without `malloc()` call. This
list contains a pointer to the some pool. Apparently, this memory
is taken from a previously used pool. But at the same time, the
memory that this pointer points to looks as has never been
touched by any D code. I haven't figured out why this is so yet.
Perhaps there is some error in calculating pointers.
Also, during inside of `allocPage`, execution flow gets to the
line:
```
void* p = baseAddr + pn * PAGESIZE;
```
but at same time baseAddr == 0xf0f0f0f0f0f0f0f0f0 (result of
MEMSTOMP)
More information about the Digitalmars-d
mailing list