Any fields in injected classes are being collected by garbage collector. This includes both fields coming from parent classes, and injected ones.
Fields which store a class, which is also stored somewhere, where it is recognized by garbage collector stops that. For example any Unity Game Objects and Components are not collected, as they are stored in Unity hierarchy.
When this happens field's wasCollected property is never set, in fact the object is replaced by some random allocated object. This causes severe data corruption if such classes are introduced into game state.
Steps to Reproduce
Create an injected class like this, and add it to any Game Object on Load()
public class TestClass : MonoBehaviour
{
public Il2CppReferenceField<List<MyClass>> myClassList;
public TestClass(IntPtr ptr) : base(ptr) { }
private GCHandle myClassListHandle;
private void Awake()
{
// In awake I initialize the field
List<MyClass> list = new List<MyClass>();
// Remove this line to remove the temporary fix
myClassListHandle = GCHandle.Alloc(list, GCHandleType.Normal);
myClassList.Set(list);
}
private void OnDestroy()
{
// Remove this line to remove the temporary fix
myClassListHandle.Free();
}
}
MyClass can be any class. For example a AudioClip, or some other serialized class.
Now check the value of the myClassList field after the game has loaded fully. It will contain garbage object, which is likely is not even related to original class. It will not contain any data you store there.
In the snippet I also included a temporary fix I found. If I create a GCHandle for my field object, it will not get collected.
Issue
Any fields in injected classes are being collected by garbage collector. This includes both fields coming from parent classes, and injected ones.
Fields which store a class, which is also stored somewhere, where it is recognized by garbage collector stops that. For example any Unity Game Objects and Components are not collected, as they are stored in Unity hierarchy.
When this happens field's
wasCollected
property is never set, in fact the object is replaced by some random allocated object. This causes severe data corruption if such classes are introduced into game state.Steps to Reproduce
Create an injected class like this, and add it to any Game Object on
Load()
MyClass
can be any class. For example aAudioClip
, or some other serialized class.Now check the value of the
myClassList
field after the game has loaded fully. It will contain garbage object, which is likely is not even related to original class. It will not contain any data you store there.In the snippet I also included a temporary fix I found. If I create a
GCHandle
for my field object, it will not get collected.