Closed evertheylen closed 5 years ago
let's see here, your stack trace says it is entering the hashed index remove at references.d#L298, which goes into _RemoveAll at multi_index.d#L3885, which eventually eventually gets to _Remove, which should be calling removeFirst, which looks like it is failing to set the prev pointer to null when the next pointer is null, but otherwise isn't calling insertNext or insertPrev.
I don't remember exactly what magic is going on wrt signals, but perhaps remove is calling _NotifyChanges at some point, which is calling _Remove on a first node and failing to clear prev, and then calling insertNext with that node
Could you determine if this is happening, eg with if(isFirst(node)) writeln("Tada!");
just before line 3624 or just after 3611?
I don't think it's happening, at least I didn't get the output I would expect. I added a bunch more debug prints, maybe they are useful to you? They also refer to line numbers, which do not line up anymore, so see this fork. I made a log (with the assert commented out) and a full stacktrace (with the failing assert).
your stack trace has assert(next);
in removeNext originating the exception, but the python exception message suggests it's the line in insertNext. That's weird. so insertNext could be called from _NotifyChanges, _Insert, insert, or reserve. Actually, it looks like the reserve call would trigger the assertion. since it's passing a first node to insertNext. I'll try and worry out a repro
does master fix this issue for you?
does master fix this issue for you?
Yes! Thanks a lot :)
I'm having a rather curious bug. Let me start with saying that I never programmed in D before, but I'm working with the PSI Solver in Python (through psipy). Sadly, I can't share the code that actually triggers this bug (it would be very complex to set up anyway).
Either way, I tried my best to debug the issue by myself. Here's the interesting part of the stacktrace:
Somehow, the stacktrace doesn't show the actual frame at which the assertion fails. Either way, this code is the culprit:
Commenting out this assert makes my program work. The value of
node.index!N.prev
that makes the assert fail, is simply 176 or 0xb0 (remains the same between different runs). That's definitly not a valid pointer, so I started checking each assignment to '.prev' in the code. It turns out the value is set by some "BucketHackery" code:I don't know much about the concept of 'versions' in D, but this static assert prevents me from commenting out
version = BucketHackery
.So my hypothesis is as follows: BucketHackery, as the name implies, is some hackery code to wrangle out some extra performance in exchange for some complex tricks. The values set by BucketHackery are not supposed to ever 'leak' to
insertNext
, but in this case they do. Luckily a pointer of value 0xb0 can still kind of be considered null, so commenting out the assert does not actually harm anything.I'm not sure how to proceed. I could use some help at creating a minimal verifiable example, I don't even really know what
multi_index
is used for. I can of course provide more details or run tests if needed.Some details about my environment: