bugfix(contain): Restore retail compatibility after crash fix in OpenContain::killAllContained#2439
Conversation
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp | Reverts the swap-to-empty approach from PR #921 and replaces it with an in-place erase-then-reset-iterator loop, so that onRemoving sees the live (shrinking) list size during each iteration — restoring correct "last occupant" semantics for GarrisonContain. Logic is sound; null-element cleanup is deferred to the final safety clear(). |
Sequence Diagram
sequenceDiagram
participant KC as killAllContained
participant CL as m_containList
participant OC as onRemoving
participant RD as rider
KC->>CL: it = begin()
loop while it != end()
KC->>CL: rider = *it
KC->>CL: erase(it) / --m_containListSize
KC->>OC: onRemoving(rider)
Note over OC: Sees updated list size<br/>(correct "last occupant" check)
KC->>RD: onRemovedFrom(container)
KC->>RD: kill()
Note over KC,RD: kill() may recursively<br/>drain m_containList
KC->>CL: it = begin()
end
KC->>CL: ASSERT empty, then clear() / size=0
Last reviewed commit: "Updated comments."
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp
Show resolved
Hide resolved
…OpenContain::killAllContained.
04af4f6 to
341c271
Compare
|
Does this still prevent the crashing with tech terrors? |
Yes, the original crash is still fixed. I made sure of that, and also created a reproduction of it in the crash fix PR. |
xezon
left a comment
There was a problem hiding this comment.
Logic looks plausible. Comments need polishing.
| // on the death of the host container. This is reproducible by shooting with | ||
| // Neutron Shells on a GLA Technical containing GLA Terrorists. | ||
| // Neutron Shells on a GLA Technical containing GLA Toxin Terrorists | ||
| // with the Chem_SuicideWeapon upgrade, which is automatically granted by the GLA Toxin Command Center. |
There was a problem hiding this comment.
Too much additional information in my opinion.
| DEBUG_ASSERTCRASH( rider, ("Contain list must not contain null element")); | ||
| if ( rider ) | ||
| { | ||
| // TheSuperHackers @bugfix Caball009 11/03/2026 The contain list must be updated while iterating over it. |
There was a problem hiding this comment.
I suggest merge this description with the one above.
There was a problem hiding this comment.
I could use some suggestions as to what information you want to retain from your own comment.
There was a problem hiding this comment.
The important part is the repro and the technical error it caused.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp
Outdated
Show resolved
Hide resolved
|
Updated the comments. I got rid of the old 'Neutron Shells + GLA Technical containing GLA Terrorists' issue reproduction description that seems too detailed to me. |
The way the crash fix was implemented in #921 assumes that the logic behavior doesn't change if
m_containList/m_containListSizeis already empty with the first iteration. This is not the case in the attached replay in #2215.If
m_containList/m_containListSizeis empty, it'll make garrisoned civilian buildings unoccupied on the first iteration instead of the last iteration, and the GLA Demolition upgrade would cause damage to the building for each occupant instead of just the last one when hit with a neutron shell.garrisoned_gla_demolition_upgrade_neutron_shell_incorrect.mp4
garrisoned_gla_demolition_upgrade_neutron_shell_correct.mp4
Pay attention to the health of the civilian building. In the correct version, only the detonation of the last GLA RPG Trooper causes damage instead of every one.
TODO: