Fix crash on exit when C# code was bound to asset unloading event called after C# shutdown
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
MDomain* MRootDomain = nullptr;
|
||||
MDomain* MActiveDomain = nullptr;
|
||||
Array<MDomain*, FixedAllocation<4>> MDomains;
|
||||
bool MCore::Ready = false;
|
||||
|
||||
MClass* MCore::TypeCache::Void = nullptr;
|
||||
MClass* MCore::TypeCache::Object = nullptr;
|
||||
@@ -301,6 +302,11 @@ bool MProperty::IsStatic() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void MCore::OnManagedEventAfterShutdown(const char* eventName)
|
||||
{
|
||||
LOG(Error, "Found a binding leak on '{}' event used by C# scripting after shutdown. Ensure to unregister scripting events from objects during disposing.", ::String(eventName));
|
||||
}
|
||||
|
||||
MDomain* MCore::GetRootDomain()
|
||||
{
|
||||
return MRootDomain;
|
||||
|
||||
@@ -57,6 +57,10 @@ public:
|
||||
static void UnloadScriptingAssemblyLoadContext();
|
||||
#endif
|
||||
|
||||
// Utility for guarding against using C# scripting runtime after shutdown (eg. when asset delegate is not properly disposed).
|
||||
static bool Ready;
|
||||
static void OnManagedEventAfterShutdown(const char* eventName);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Utilities for C# object management.
|
||||
|
||||
@@ -316,7 +316,8 @@ bool MCore::LoadEngine()
|
||||
|
||||
char* buildInfo = CallStaticMethod<char*>(GetStaticMethodPointer(TEXT("GetRuntimeInformation")));
|
||||
LOG(Info, ".NET runtime version: {0}", ::String(buildInfo));
|
||||
MCore::GC::FreeMemory(buildInfo);
|
||||
GC::FreeMemory(buildInfo);
|
||||
Ready = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -327,6 +328,7 @@ void MCore::UnloadEngine()
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
CallStaticMethod<void>(GetStaticMethodPointer(TEXT("Exit")));
|
||||
Ready = false;
|
||||
MDomains.ClearDelete();
|
||||
MRootDomain = nullptr;
|
||||
ShutdownHostfxr();
|
||||
|
||||
@@ -2043,6 +2043,7 @@ namespace Flax.Build.Bindings
|
||||
contents.Append(')').AppendLine();
|
||||
contents.Append(" {").AppendLine();
|
||||
contents.Append(" static MMethod* method = nullptr;").AppendLine();
|
||||
contents.AppendFormat(" if (!MCore::Ready) {{ MCore::OnManagedEventAfterShutdown(\"{0}.{1}\"); return; }}", classTypeNameManaged, eventInfo.Name).AppendLine();
|
||||
contents.AppendFormat(" if (!method) {{ method = {1}::TypeInitializer.GetClass()->GetMethod(\"Internal_{0}_Invoke\", {2}); CHECK(method); }}", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine();
|
||||
contents.Append(" MObject* exception = nullptr;").AppendLine();
|
||||
if (paramsCount == 0)
|
||||
|
||||
Reference in New Issue
Block a user