Skip to content

Keep interior camera markers alive between SetCameraPos calls - #216

Closed
IvanPerrella wants to merge 1 commit into
TheMoonPeople:masterfrom
IvanPerrella:fix/interior-camera-dangling-pointer
Closed

IvanPerrella wants to merge 1 commit into
TheMoonPeople:masterfrom
IvanPerrella:fix/interior-camera-dangling-pointer

Conversation

@IvanPerrella

Copy link
Copy Markdown
Contributor

Summary

Fixes a crash (0xC0000005, access violation) when walking between fixed-camera zones inside an interior.

SetCameraPos (port/src/edit_in.cpp) builds the interior's camera markers into a local list every frame, and the file-static active_camera keeps a pointer to one of those entries across frames (it lingers on the old marker for camera_change_count frames after the player leaves its box). 98580bd moved that list from a stack array to a per-call std::make_unique allocation, so from the next call on active_camera points at freed heap memory. Walking from one camera zone to another then reads garbage in CFrame::GetLWMatrix and crashes.

The PS2 code only worked because its INTERIOR_CAMERA cameras[8] stack array sat at the same address every frame, so the stale pointer landed on the entry rebuilt for that frame. This change gives the list static storage, which keeps that behaviour without relying on stack layout. active_camera is still reset to null on interior init.

Backtrace (windows-x64 Debug, PAL, house i01h06)

* thread #1, stop reason = Exception 0xc0000005: Access violation reading location 0xffffffffffffffff
  frame #0: CFrame::GetLWMatrix(...) at frame.cpp:530:9        // frame->attr.billboard, frame = 0x41ea994b40f7f186 (float data)
  frame #1: CFrame::GetWorldPosition(...) at frame.cpp:822:5
  frame #2: SetCameraPos(...) at edit_in.cpp:1496:30            // active_camera->frame.GetWorldPosition(eye, eye)
  frame #3: EditInLoop() at edit_in.cpp:545:9
  frame #4: EditLoop() at editloop.cpp:271:31

Test plan

  • build.bat windows-x64 and build.bat windows-x64-release build on Windows 11
  • Reproduced the crash in Release and Debug before the change (same interior, after picking up the key item)
  • After the change, the same interior plays through under lldb and the game exits normally (status 0)

🤖 Generated with Claude Code

active_camera holds a pointer into SetCameraPos's camera list across frames.
98580bd moved that list from the stack to a per-call heap allocation, so the
pointer dangled after each call and walking between camera zones in an
interior read freed memory and crashed in CFrame::GetLWMatrix. The PS2 code
only worked because its stack array sat at the same address every frame;
give the list static storage so the remembered entry is the one rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SirFancyBacon

SirFancyBacon commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

I believe this is a duplication of #213

Thank you for the PR though!

Adubbz added a commit that referenced this pull request Oct 24, 2026
Also resolves #214 and supersedes #216 (same crash, stale-pointer approach).
@Adubbz

Adubbz commented Oct 24, 2026

Copy link
Copy Markdown
Member

Superseded by #213, now on master: SetCameraPos keeps the active camera as an index into the per-frame list instead of a pointer, which fixes the same crash (#214) without relying on the list's address. Thank you for the detailed backtrace!

@Adubbz Adubbz closed this Oct 24, 2026
@IvanPerrella
IvanPerrella deleted the fix/interior-camera-dangling-pointer branch October 25, 2026 10:28
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.

3 participants