Plug In Crashing When Using TaskGraph

So, I’m working on a MarchingCubes plugin, and it generally works well. However, I’m attempting to implement a TaskGraph event to speed up the filling of a 3D Noise Texture.

I’ve been looking at the great BrickGame as a reference for how a few things are done, and have attempted to implement a TaskGraph the way Andrew has done it.

It works fine in the program. However, when I’m in debug mode, and exit out of Unreal, a breakpoint is triggered throwing up an error message:

Assertion failed: ModuleInfo->Module.IsUnique() [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.10\Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp] [Line: 502]

This is only triggered if I use the TaskGraph system. If I do not use it, there is no error.

For reference, here’s the section of code I’m using:

//pre-fill a lookup 3d texture to avoid having to constantly do calls to the 3d Sampler
void FOpenSourceMarchingCubes::Fill3DTexture(int32 inOffsetX, int32 inOffsetY, int32 inOffsetZ, int32 Dimension)
{
	NoiseTextureVolume.Empty();

	NoiseTextureVolume.AddUninitialized(Dimension*Dimension*Dimension);

	FGraphEventArray XTaskGraphItem;

	for (int32 X = 0; X < Dimension; X++)
	{
		XTaskGraphItem.Add(FFunctionGraphTask::CreateAndDispatchWhenReady([&, X]()
			{
			for (int32 Y = 0; Y < Dimension; Y++)
			{
				for (int32 Z = 0; Z < Dimension; Z++)
				{
					NoiseTextureVolume[Dimension * Dimension * X + Dimension * Y + Z] = (Density(inOffsetX +  X * fStepSize, inOffsetY + Y * fStepSize, inOffsetZ + Z * fStepSize));
				}
			}
		}, TStatId(), NULL));
	}

	// Wait for XTaskGraphItem tasks to complete.
	FTaskGraphInterface::Get().WaitUntilTasksComplete(XTaskGraphItem, ENamedThreads::GameThread);
}

Thoughts?

If you have assertion fail this means some condition failed and engine controllably crashed, the error shows you boolean condition (same as you use in “if”) that failed and point where it failed (which is usally check() function which checks that condition). In such case go there and see where this happens (debug should show you too)

In you case this happens on UnloadModule on one of the modules (look on stack to see which or look on log which module is unloaded right before crash), there description saying what going on (thats why i recommanded you to check code where this happens, this is very helpful):

https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/Core/Private/Modules/ModuleManager.cpp#L501

// Verify that we have the only outstanding reference to this module.  No one should still be 
// referencing a module that is about to be destroyed!
check( ModuleInfo->Module.IsUnique() );

Which means something is still using the module, there for it can’t be unloaded or else you would have a crash as running code would start to call functions in nonallocated memory. My guess is it has to do with TaskGraph still on the go referencing to this module maybe.

The problem turned out to be that the module was instantiating the plugin and calling its PLUGIN_NAME::Get() function inside a function inside the taskgraph. You’re not supposed to create UObjects or the like inside the taskgraph. Moving the instantiation and the Get() to outside the taskgraph fixed the issue.