Skip to content

Fix segfaults when P_RemoveMobj is called from MobjSpawn hook

Hanicef requested to merge Hanicef/SRB2:fix-segfault-removemobj-spawn into next

When P_RemoveMobj is called from MobjSpawn, the game segfaults. This is because the P_SpawnMobj returns NULL in that case, but a large portion of the engine simply doesn't handle that. There's even a warning in a comment in P_SpawnMobj that indicates that this is an issue: https://git.do.srb2.org/Hanicef/SRB2/-/blob/next/src/p_mobj.c#L10684-L10690

This is somewhat major change that tweaks the code to handle these cases by simply checking with P_MobjWasRemoved right after P_SpawnMobj is called, and skips creation logic in case the object was removed. Of course, removing certain mobjs from a map can break all kinds of things, but my goal here is to make sure the game doesn't crash at least.

This script was used to track down missing spawn handlers:

addHook("MobjSpawn", function (mobj)
    if P_RandomByte() >= 128 then
        P_RemoveMobj(mobj)
    end
end)

Randomness was used here to make sure that cases where a child mobj fails to spawn when the parent succeeded was covered. It has been tested pretty thoroughly, but there's always a chance I've missed something in the code, especially when relying on randomness like this. If you intend to test this yourself, I strongly recommend to do so with a debugger, so missed cases can be tracked down easily!

Merge request reports