Skip to content

fix(gta/streaming): don't resolve game packfile handles when unregistering streamed files - #4111

Open
TheMadGriffin wants to merge 1 commit into
citizenfx:masterfrom
TheMadGriffin:fix/streaming-unregister-game-handle
Open

fix(gta/streaming): don't resolve game packfile handles when unregistering streamed files#4111
TheMadGriffin wants to merge 1 commit into
citizenfx:masterfrom
TheMadGriffin:fix/streaming-unregister-game-handle

Conversation

@TheMadGriffin

Copy link
Copy Markdown

Goal of this PR

Fix a reliably reproducible client crash when entering the Rockstar Editor while connected to
any server that streams a file overriding a base-game asset (occlusion ymaps, v_int_* ytyps
and similar — very common on roleplay servers).

Crash signature: EXCEPTION_ACCESS_VIOLATION reading 0x10 at GTA5_b3570.exe+1357D4F,
called from gta-streaming-five.dll+440AD, legacy hash summer-football-princess.

This is very likely the mechanism behind the long-standing scattered reports of "the Rockstar
Editor always crashes on server X but works on server Y" — whether a server happens to stream
a base-asset override decides it.

How is this PR achieving the goal

When a streamed file overrides an asset that is already registered, LoadStreamingFile.cpp
pushes the original game packfile handle (collection index >= 2) onto g_handleStack
before overwriting the entry, then pushes the new cfx raw handle on top:

// LoadStreamingFile.cpp:1934-1948 — registration, override branch
// if no old handle was saved, save the old handle
auto& hs = g_handleStack[strId + strModule->baseIdx];

if (hs.empty())
{
    hs.push_front(entry.handle);          // ORIGINAL game handle
}

entry.handle = (collectionId << 16) | idx;
g_handlesToTag[entry.handle] = tag;

// save the new handle
hs.push_front(entry.handle);              // cfx raw handle

The handle stack therefore legitimately contains handles the cfx raw streamers do not own.
The registration path already accounts for this and guards raw streamer access:

// LoadStreamingFile.cpp:1965
// only for 'real' rawStreamer (mod variant likely won't reregister)
if (streaming::IsRawHandle(entry.handle))

The matching unregistration path in CfxCollection_RemoveStreamingTag has no such guard —
it walks the whole stack and unconditionally does:

// LoadStreamingFile.cpp:2622-2634
auto rawStreamer = streaming::GetRawStreamerByIndex(streaming::GetCollectionIndex(*it));
auto entryName = rawStreamer->GetEntryName(streaming::GetEntryIndex(*it));

Rockstar Editor activation forces a disconnect whose session shutdown destroys the base
packfile collections before resources unmount. By the time the unregister loop runs,
resolving a saved game handle dereferences freed collection state.

This PR applies the same ownership check the registration side already uses, and null-checks
the returned streamer. No behaviour is lost by skipping non-raw handles: file is a resource
cache path, so it can never string-compare equal to a game packfile entry name — those
compares were dead in healthy runs and fatal during teardown.

The loop rewrite also fixes a pre-existing iterator bug, independent of the crash: the
original it = handleData.erase(it) inside a for (...; ++it) header skipped the element
following each erasure, and incremented past end() when the erased element was the last one.
The RDR3 branch is behaviourally unchanged.

Crash evidence (4 minidumps, one client, one server)
  • 3 dumps: RIP GTA5_b3570.exe+1357D4F, called from gta-streaming-five.dll+440AD; the
    crashing frame's locals contain cs6_occl_00 (an occlusion ymap override).
  • 1 dump: RIP GTA5_b3570.exe+1357D38 (same function), locals contain v_int_1.ytyp
    (a base interior ytyp override) — different session, different first override in unmount
    order.
  • Exception context in all four: RAX = 0, AV read at 0x10.
  • R* gamelog at crash time: 0 vehicles, 0 objects, 1 ped, streaming idle. All local entities
    had been deleted before activation as a mitigation attempt and the crash reproduced
    identically, so world entity state is not a factor.
  • Stopping the same resources mid-session does not crash, consistent with the collections
    still being alive at that point.

Dumps available on request.

Repro: connect to a server streaming any file whose name collides with a base-game asset
(a *_occl_*.ymap from any free MLO is the easiest source), then trigger
ACTIVATE_ROCKSTAR_EDITOR. The client crashes during the resource unmount following
HS_FORCE_DISCONNECT, before the editor appears.

This PR applies to the following area(s)

FiveM

Successfully tested on

Game builds: 3570

Platforms: Windows

Testing status — please read. This compiles clean with no new warnings, and the root cause
is established from four minidumps plus source analysis. I have not been able to complete
a runtime before/after run: a locally built gta-streaming-five.dll is rejected when dropped
into a retail client — the component loader deletes content_index.xml on the failed load and
the launcher's updater then restores the stock DLL on next start — so I could not get a
self-built component to load in a stock install to do the comparison.

If a maintainer with a dev-signed client can run it, the repro above is deterministic and
takes under a minute. Stock crashes every time; the patched build should enter the editor
cleanly. Happy to provide the dumps, the server-side repro setup, or to make any changes
requested.

Checklist

  • Code compiles and has been tested successfully. (compiles clean; runtime testing blocked — see above)
  • Code explains itself well and/or is documented.
  • My commit message explains what the changes do and what they are for.
  • No extra compilation warnings are added by these changes.

@menordoodio1333333aa-spec

Copy link
Copy Markdown
Screenshot_20260807-125041

@menordoodio1333333aa-spec

Copy link
Copy Markdown

@menordoodio1333333aa-spec

Copy link
Copy Markdown

Muito bom fivem te amooooooooooooooo muitoooooooooooooioooooooo fivem

…ering streamed files

When a streamed file overrides an already-registered base-game asset, the asset's
handle stack keeps the original game packfile handle alongside the cfx raw handle.
CfxCollection_RemoveStreamingTag walked that stack and called GetEntryName() on every
entry, including the game handle. During a session teardown that destroys collections
before resources unmount - as Rockstar Editor activation does - that dereferences
freed collection state and crashes.

Guard the compare with streaming::IsRawHandle(), matching the check the registration
path already performs, and null-check the streamer. A resource cache path can never
equal a game packfile entry name, so the skipped compares could not have matched.

Also fixes a pre-existing iterator bug in the same loop: `it = erase(it)` inside a
`for (...; ++it)` skipped the following element and incremented past end() when the
erased element was last.

Signed-off-by: TheMadGriffin <themadgriffin0@gmail.com>
@TheMadGriffin
TheMadGriffin force-pushed the fix/streaming-unregister-game-handle branch from 940ae7d to 99e3d42 Compare August 8, 2026 04:37
@github-actions github-actions Bot added the invalid Requires changes before it's considered valid and can be (re)triaged label Aug 8, 2026
@valerisn

valerisn commented Aug 8, 2026

Copy link
Copy Markdown

Hey! Quick question, and absolutely no offense intended. Is there a linked issue or existing report for this PR that I could take a look at?

Also, I may be completely wrong here, but the PR description reads a little AI-assisted to me. Was AI used anywhere while putting this together? Not asking as a criticism at all, just curious about the context and how the PR was prepared.

@TheMadGriffin

Copy link
Copy Markdown
Author

Hey Valerisn!

No offense at all! I opened this PR to resolve the long standing issue of Rockstar editor crashing when launched from in game. There have been quite a few issues opened for it. Here is one: #3389

I did use Claude Fable 5 to aid in putting this together and manually reviewed the description and code. I apologize if that is not permissible.

@valerisn

valerisn commented Aug 8, 2026

Copy link
Copy Markdown

No no its alright, I get Writing Documentation with AI, was just curious thats all

@TheMadGriffin

Copy link
Copy Markdown
Author

No no its alright, I get Writing Documentation with AI, was just curious thats all

It's crazy how good some of these tools are getting. I appreciate you taking the time to look at my PR.

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

Labels

invalid Requires changes before it's considered valid and can be (re)triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants