-
Notifications
You must be signed in to change notification settings - Fork 202
fix(memory): Fix various memory leaks (2) #2710
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
base: main
Are you sure you want to change the base?
Changes from all commits
8f1afe4
707f194
8fe08f6
d713e62
41a3d91
d87c02e
2b1c2d9
a49c810
2e0fe76
229839f
08a2a42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,5 +30,8 @@ | |
|
|
||
| AudioRequest::~AudioRequest() | ||
| { | ||
|
|
||
| if (m_usePendingEvent) | ||
| { | ||
| delete m_pendingEvent; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -262,16 +262,36 @@ void GameLogic::clearGameData( Bool showScoreScreen ) | |
| TheScriptActions->closeWindows(FALSE); // Close victory or defeat windows. | ||
|
|
||
| Bool shellGame = FALSE; | ||
| if ((!isInShellGame() || !isInGame()) && showScoreScreen && !TheGlobalData->m_headless) | ||
| if (showScoreScreen) | ||
| { | ||
| shellGame = TRUE; | ||
| TheTransitionHandler->setGroup("FadeWholeScreen"); | ||
| TheShell->push("Menus/ScoreScreen.wnd"); | ||
| TheShell->showShell(FALSE); // by passing in false, we don't want to run the Init on the shell screen we just pushed on | ||
| TheTransitionHandler->reverse("FadeWholeScreen"); | ||
|
|
||
| void FixupScoreScreenMovieWindow(); | ||
| FixupScoreScreenMovieWindow(); | ||
| if ((!isInShellGame() || !isInGame()) && !TheGlobalData->m_headless) | ||
| { | ||
| shellGame = TRUE; | ||
| TheTransitionHandler->setGroup("FadeWholeScreen"); | ||
| TheShell->push("Menus/ScoreScreen.wnd"); | ||
| TheShell->showShell(FALSE); // by passing in false, we don't want to run the Init on the shell screen we just pushed on | ||
| TheTransitionHandler->reverse("FadeWholeScreen"); | ||
|
|
||
| void FixupScoreScreenMovieWindow(); | ||
| FixupScoreScreenMovieWindow(); | ||
|
|
||
| destroyQuitMenu(); | ||
| } | ||
|
|
||
| // TheSuperHackers @info The game info may have been allocated on save game load. | ||
| // Deallocate it here until there's a better place to do it. | ||
| if (TheSkirmishGameInfo) | ||
| { | ||
| delete TheSkirmishGameInfo; | ||
| TheSkirmishGameInfo = nullptr; | ||
| TheGameInfo = nullptr; | ||
| } | ||
| else if (TheChallengeGameInfo) | ||
| { | ||
| delete TheChallengeGameInfo; | ||
| TheChallengeGameInfo = nullptr; | ||
| TheGameInfo = nullptr; | ||
| } | ||
|
Comment on lines
+283
to
+294
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The same applies to A targeted fix would guard these deletions to only run when the game info was allocated during a save-game load (e.g. by checking an additional flag or by only deleting when Prompt To Fix With AIThis is a comment left during a code review.
Path: Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp
Line: 283-294
Comment:
**`TheChallengeGameInfo` deletion breaks the challenge campaign "Next Mission" flow**
`clearGameData(TRUE)` (which shows the score screen) now unconditionally deletes `TheChallengeGameInfo`. In `ScoreScreen.cpp`, `startNextCampaignGame()` immediately asserts `TheChallengeGameInfo != nullptr` (line 200) before re-configuring it for the next mission. Since `clearGameData()` runs _before_ the score screen updates, `TheChallengeGameInfo` is already null by the time the player clicks "Next Mission", causing an assertion failure / crash on every challenge campaign mission transition.
The same applies to `TheSkirmishGameInfo` being set to null before `ScoreScreenUpdate()` uses `TheGameInfo` (line 428 of `ScoreScreen.cpp`) to start score-screen music, silently breaking score-screen music for all regular skirmish games.
A targeted fix would guard these deletions to only run when the game info was allocated during a save-game load (e.g. by checking an additional flag or by only deleting when `isLoadingSave()` was true).
How can I resolve this? If you propose a fix, please make it concise.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point.
This doesn't fix the crash that happens when restarting a challenge match from the 'score screen'. I could use some suggestions where these deallocations are better suited to take place. |
||
| } | ||
|
|
||
| TheGameEngine->reset(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2236,6 +2236,11 @@ void MilesAudioManager::processRequestList() | |
|
|
||
| if (!req->m_requiresCheckForSample || checkForSample(req)) { | ||
| processRequest(req); | ||
|
|
||
| // TheSuperHackers @info Deallocating the audio event is no longer responsibility of this request, | ||
| // because it was just processed. Reset fields to avoid use after free and double free. | ||
| req->m_usePendingEvent = false; | ||
| req->m_pendingEvent = nullptr; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Who is deallocating it?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll probably rewrite this a bit to make it clearer, and put in a separate PR. |
||
| } | ||
| deleteInstance(req); | ||
| it = m_audioRequests.erase(it); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.