Skip to content

Fix GC reference tracking for injected classes - #276

Open
Pietrodjaowjao wants to merge 1 commit into
BepInEx:masterfrom
Pietrodjaowjao:master
Open

Fix GC reference tracking for injected classes#276
Pietrodjaowjao wants to merge 1 commit into
BepInEx:masterfrom
Pietrodjaowjao:master

Conversation

@Pietrodjaowjao

Copy link
Copy Markdown

Problem

ClassInjector does not propagate the base class's has_references flag or update it when adding reference-containing fields to an injected class.

In addition, Il2CppReferenceField.Set() and Il2CppStringField.Set() write object pointers directly:

*GetPointerToData() = value;

This bypasses IL2CPP's GC write barrier. Together, the incorrect class metadata and raw reference writes can cause the collector or Unity liveness processing to miss objects reachable through injected fields. Those objects may then be reclaimed while still referenced, resulting in intermittent native access violations.

This is mostly relevant for injected types that inherit from base classes containing references.

Change

  • Propagate has_references from the injected class's base class.
  • Set has_references when an injected field is:
    • a reference type; or
    • a value type that itself contains references.
  • Use il2cpp_gc_wbarrier_set_field when assigning injected reference and string fields.
  • Fall back to the existing raw pointer write when the native write-barrier export is unavailable.
  • Expose HasReferences through INativeClassStruct.
  • Validate the native field class pointer before querying its metadata.

Classes without references retain their previous metadata and layout. Unity versions without the write-barrier export retain the previous field-write behavior through the fallback, so existing setups remain unaffected.

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