Not signed in
Copyright © 2026 Unity Technologies
If il2cpp is shutdown/restarted multiple times (such as when running LoadUnload tests) there is a use-after-free case shown here:
static void PopulateArrayGenericMethods(Il2CppClass* klass, uint16_t offset, const GenericArrayMethods& genericArrayMethods) { for (int i = 0; i < klass->interface_offsets_count; i++) { Il2CppClass* interfaceType = klass->interfaceOffsets[i].interfaceType; if (!interfaceType->generic_class) continue; Il2CppClass* interfaceDefinition = GenericClass::GetTypeDefinition(interfaceType->generic_class); Il2CppGenericContext context = { 0 }; context.method_inst = MetadataCache::GetGenericInst(&interfaceType->generic_class->context.class_inst->type_argv[0], 1); for (GenericArrayMethods::const_iterator iter = genericArrayMethods.begin(); iter != genericArrayMethods.end(); ++iter) { Crash ==> if (iter->interfaceMethodDefinition->klass != interfaceDefinition)
because iter->interfaceMethodDefinition can point to free'd memory. The memory comes from s_MetadataMemoryPool in MetadataAlloc.cpp . Method data is only setup once per run (even if il2cpp is shutdown/restarted) when GetArrayGenericMethodsCount() is run from static void SetupArrayMethods(Il2CppClass* arrayClass) . Reason it isnt rebuilt is a check for vector size here:
static size_t GetArrayGenericMethodsCount() { if (s_GenericArrayMethods.size() == 0) CollectGenericArrayMethods(s_GenericArrayMethods); return s_GenericArrayMethods.size(); }
Steps to reproduce:
1) Setup basic checks in Application Verifier for exe built by LoadUnload test (il2cppLoadUnloadTest.exe on windows) or zero memory pointed to by s_MetadataMemoryPool in MetadataAlloc.cpp before its deleted.
2) Run VerifyIL2CPPLoadUnloadStressTest(DoNotUnloadDynamicLibrary) test in Rider/cmd line
3) Crash
Sign in to see your voted issues