Skip to content

Conversation

@bobtista
Copy link

In headless mode, instead of going through the normal game cleanup (which has the use-after-free bug), we can just call exit(0) to terminate immediately.

@greptile-apps
Copy link

greptile-apps bot commented Jan 29, 2026

Greptile Overview

Greptile Summary

Added early exit(0) in headless mode when replay playback ends, bypassing normal game cleanup to prevent a use-after-free crash that occurs during TheGameEngine->reset() in debug builds.

The fix is pragmatic and appropriate for headless mode, which has no UI and is terminating anyway. The comment clearly documents the rationale.

Confidence Score: 4/5

  • This PR is safe to merge with low risk - it's a targeted workaround for a specific debug crash in headless mode
  • The fix appropriately uses exit(0) to skip problematic cleanup in headless mode where no UI exists and the process is terminating. The comment clearly documents the use-after-free issue. However, the root cause in TheGameEngine->reset() remains unfixed, and this is explicitly a workaround rather than a proper fix
  • No files require special attention

Important Files Changed

Filename Overview
GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp Added early exit with exit(0) in headless mode during replay cleanup to prevent use-after-free crash in debug builds

Sequence Diagram

sequenceDiagram
    participant Replay as Replay Playback
    participant Recorder as RecorderClass::stopPlayback()
    participant GlobalData as TheGlobalData
    participant GameLogic as TheGameLogic
    participant OS as Operating System

    Replay->>Recorder: End of replay reached
    Recorder->>Recorder: Close file
    Recorder->>Recorder: Check !m_doingAnalysis
    
    alt Headless Mode (NEW)
        Recorder->>GlobalData: Check m_headless flag
        GlobalData-->>Recorder: true
        Note over Recorder: Skip normal cleanup to avoid use-after-free
        Recorder->>OS: exit(0)
        Note over OS: Process terminates, OS reclaims resources
    else Normal Mode
        Recorder->>GlobalData: Check m_headless flag
        GlobalData-->>Recorder: false
        Recorder->>GameLogic: exitGame()
        Note over GameLogic: Normal game cleanup<br/>(can trigger use-after-free in debug builds)
    end
Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant