Raw UFastGeoContainer* pointer assigned to a memory chunk getting GC'd

Hi,

We are getting some crashes when Loading into a new level.

Basically we end up with FastGeo = 0xdddddddd

FJob::FastGeo is a raw UFastGeoContainer* pointer assigned to a memory chunk getting GC’d.

So far we seem to have a fix which essentially turns the raw pointer in a Weak Object Pointer.

Is this an issue you’ve been tracking? Can you evaluate our suggested fix?

Thanks,

David

//FastGeoAsyncRenderStateJobQueue.h
//--------------------------------------
struct FJob
{
  ...
  bool IsValid() const { return FastGeo.IsValid(); }
  ...
  friend inline uint32 GetTypeHash(const FJob& InJob)
  {
    return HashCombine(GetTypeHash(InJob.FastGeo), GetTypeHash(InJob.Type));
  }
  ...
  TWeakObjectPtr<UFastGeoContainer> FastGeo;
  ...
}

//FastGeoAsyncRenderStateJobQueue.cpp
//--------------------------------------
void FFastGeoAsyncRenderStateJobQueue::AddJob(const FJob& Job)
{
  ...
        FGCScopeGuard GCGuard;// Prevent GC in this scope
	check(Job.IsValid());
  ...
}


void FFastGeoAsyncRenderStateJobQueue::FJob::Execute() const
{
        FGCScopeGuard GCGuard; // Prevent GC in this scope
	if (IsValid())
  {
    ...
  }
}


void FFastGeoAsyncRenderStateJobQueue::FJob::OnPostExecute_GameThread() const
{
        FGCScopeGuard GCGuard; // Prevent GC in this scope
	if (IsValid())
  {
    ...
  }
}



[Attachment Removed]

Hi,

The proposed fix is mostly a protection to avoid crashing and I am worried that the GCGuards will affect the performance. It might be better to flush the AsyncRenderStateJobQueue when a world is being shutdown prior to loading the new one.

void UFastGeoWorldSubsystem::Deinitialize()
{
...
 
        // Flush async jobs while their containers are still alive:
	while (AsyncRenderStateJobQueue.IsValid())
	{
		ProcessAsyncRenderStateJobs(/*bWaitForCompletion=*/ true);
	}
 
	Super::Deinitialize();
}

I’m trying to validate this flush but it might take some time setting up with a project that reproduces the crash.

It would useful if you validate it and let me know if that resolves the problem.

Martin

[Attachment Removed]

Hi.

It turns out that we recently fixed that bug in the UE6 stream. It should be an easy integration in the 5.8 code. The solution is close to yours but avoids the GC guards which could affect performance. The CL is 57638612.

We are looking at backporting it to UE5 but I don’t have an ETA.

Regards,

Martin

[Attachment Removed]

Hi Martin,

Appreciate the feedback, will give your fix a try and will keep you posted.

However are we expecting this forced flush to have less of an impact on perf then GC guards?

Thanks,

David

[Attachment Removed]