-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Segfault when mininuking a motorcycle #5285
Comments
processing active items is bugged
The same happens when you drop 1000 glass items and an active mininuke (in that order!) on a tile and wait for it to explode. The explosion destroys the glass items and thereby changes the items vector, the mininuke is now not the 1001. item in that vector but more like the 750. item. |
I believe it goes over the vehicles in reverse order in case a vehicle gets destroyed. It doesn't seem to properly handle parts being removed, though. It's C++'s version of a ConcurrentModificationException, in that we're essentially modifying a list being iterated over and Bad Things™ happen as a result. |
It's also possible that the problem is due to my recent fix that made explosions call vehicle->damage() as well as map->bash(). |
I can't seem to reproduce this, I've dropped the mininuke inside the motorcycle box 2 in a row but no crash happened after the explosions. But I've tried dropping 1000 glass items and activating a mininuke after setting the timer to 15 and a segfault did happen when it exploded. |
Apparently it doesn't happen all the time. But I can still sometimes trigger it. The problematic code is still there. |
I think this is a new version of the "explosion displaces the explosive" bug we keep getting. How about we pop active items off the map before evaluating them to protect them from side effects like this? It shouldn't hurt non-explosives, and explosives can just be discarded since they destroy themselves. I actually got a segfault out of vector.size() once >_< |
You know, I learned something today. You see, BevapDin's offhand parenthetical question was the answer to our dilemma. After researching the various properties of std::vector, I was informed that erasing an element from a vector invalidates any iterators that point to elements AFTER that element. So, we all should make our vector iterators run backwards, and they will get along better with each other. PR #5792 (Edit: I'm not actually trying to say EVERY iterator on a vector should be reversed. I'm a little out of it from an extended caffeine and code binge, and it sounded funny when I wrote it.) |
@Graywolfe813 Yes, that's correct - reverse-order iterators are generally done for two reasons:
As such, the rule of thumb is to use a reverse-order iterator when potentially erasing data structure elements. |
I suppose I should have noted it here, too. That PR only fixes the crash with putting it INSIDE the box, as detailed in the initial issue report. |
I thought I noted this here before. I think a good, permanent solution to this problem will be to pull the item currently being processed off the map, process it (including triggering an explosion, which is what causes problems), then re-insert it if it's still supposed to exist instead of removing it if it doesn't. |
You did. If I had any idea how to accomplish that, I'd implement it. ;-/ Update: 15 glass items and an explosive (in that order) still segfaults. |
One less blocker in the queue. |
I realize this is a somewhat obscure bug, but...
Successfully reproduced this several times in a row. Doesn't happen if the mininuke is dropped on the ground next to the motorcycle, or if a bigger vehicle (such as a car) is used.
The text was updated successfully, but these errors were encountered: