On 2015-06-26 14:27, Maxime Chevalier-Boisvert wrote:
I seem to have run into a heisenbug involving destructors and the GC.
I'm kind of stuck at this point and need help tracking down the issue.
I put the broken code in a branch called heisenbug on github:
https://github.com/higgsjs/Higgs/tree/heisenbug
The problem manifests itself on runs of `make test` (my unittests), but
only some of the time. I wrote a script to run `make test` repeatedly to
try and find a solution:
https://github.com/higgsjs/Higgs/blob/heisenbug/source/repeatmaketest.py
The problem usually manifests itself after 5 to 15 runs on my machine. I
get a segmentation fault, not always in the same place. The randomness
seems to stem from address space randomization.
It seems the issue is caused by my freeing/reinitializing the VM during
unit tests. More specifically, commenting out this line makes the
problem go away:
https://github.com/higgsjs/Higgs/blob/heisenbug/source/runtime/vm.d#L741
Higgs can run all of my benchmarks without ever failing, but restarting
the VM during `make test` seems to be causing this problem to happen.
It's not impossible that there could be another underlying issue, such
as the JITted code I generate corrupting some memory location, but it
would seem that if this were the case, the issue would likely show up
outside of unit tests. Any help would be appreciated.
This might come as a surprise to you as much as it did to me at the
time, but when you have GCRoot* root; where GCRoot is a struct, if you
destroy(root), you're setting your local pointer to null. You're not
actually calling the destructor on the struct.
Also, I would avoid throwing of any type in a destructor.
https://github.com/higgsjs/Higgs/blob/0b48477120c4acce46a01b05a1d4b035aa432550/source/jit/codeblock.d#L157