Fix crash from engineFreeModel racing destroyElement deferred deletion#4970
Merged
Lpsd merged 1 commit intoJun 21, 2026
Merged
Conversation
destroyElement() defers the native entity's actual removal to the next pulse. If a script frees a model in the same tick it destroyed an entity using it, that entity is still alive in the game world and other entities' collision processing can still find it the moment its collision data is freed, crashing the client. Flush the deferred deletion queue first so any such entity is fully gone before the model is freed.
Lpsd
approved these changes
Jun 21, 2026
Lpsd
pushed a commit
to Lpsd/mtasa-blue
that referenced
this pull request
Jun 22, 2026
multitheftauto#4970) ### Summary `engineFreeModel` now flushes the deferred element-deletion queue before freeing a models collision/DFF data. ### Motivation Calling `engineFreeModel` right after `destroyElement` on an entity using that model crashes the game. `destroyElement` only flags the element and defers the actual native entity deletion to the next pulse (see `CElementDeleter`). If a script frees the model in the same tick, the native entity is still alive in the game world, and another entity's collision processing (`CEntity::GetIsTouching`/`GetBoundRadius`, called from `CPhysical::ProcessCollisionSectorList`) can still find it and read its now-freed `CColModel`, crashing with an access violation. Closes multitheftauto#3316 ### Test plan - Reproduced the crash using `engineFreeModel` called immediately after `destroyElement` on a vehicle using a custom-content model. - Applied the fix and confirmed the same sequence no longer crashes. ### Checklist * [x] Your code should follow the [coding guidelines](https://wiki.multitheftauto.com/index.php?title=Coding_guidelines). * [x] Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
engineFreeModelnow flushes the deferred element-deletion queue before freeing a models collision/DFF data.Motivation
Calling
engineFreeModelright afterdestroyElementon an entity using that model crashes the game.destroyElementonly flags the element and defers the actual native entity deletion to the next pulse (seeCElementDeleter). If a script frees the model in the same tick, the native entity is still alive in the game world, and another entity's collision processing (CEntity::GetIsTouching/GetBoundRadius, called fromCPhysical::ProcessCollisionSectorList) can still find it and read its now-freedCColModel, crashing with an access violation.Closes #3316
Test plan
engineFreeModelcalled immediately afterdestroyElementon a vehicle using a custom-content model.Checklist