Steps to Reproduce
用XCode联调真机进行Crash的复现,每次都是在进入关卡之后的0-5秒内,现场如图
[Image Removed]
直接崩溃原因是在MetalPipeline.cpp的GetRenderPipeline方法中的这一段代码
`if (Desc == nullptr)
{
// By default there’ll be more threads trying to read this than to write it.
EventsMutex.ReadLock();
// Try to find a pipeline creation event for this key. If it’s found, we already have a thread creating this pipeline and we just have to wait.
TSharedPtr<FPThreadEvent, ESPMode::ThreadSafe> Event = PipelineEvents.FindRef(Key);
EventsMutex.ReadUnlock();
bool bCompile = false;
if (!Event.IsValid())
{
// Create an event other threads can use to wait if they request the same pipeline this thread is creating
EventsMutex.WriteLock();
Event = PipelineEvents.FindRef(Key);
if (!Event.IsValid())
{
Event = PipelineEvents.Add(Key, MakeShareable(new FPThreadEvent()));
Event->Create(true);
bCompile = true;
}
check(Event.IsValid());
EventsMutex.WriteUnlock();
}
if (bCompile)
{
const double CompilationStartTime = FPlatformTime::Seconds();
Desc = CreateMTLRenderPipeline(Device, bSync, Key, Init, State);
const float CompilationDuration = static_cast(FPlatformTime::Seconds() - CompilationStartTime);
AccumulatePSOMetrics(CompilationDuration);
if (Desc != nullptr)
{
PipelineMutex.WriteLock();
Pipelines.Add(Key, Desc);
ReverseLookup.Add(Desc, Key);
PipelineMutex.WriteUnlock();
}
EventsMutex.WriteLock();
Event->Trigger();
PipelineEvents.Remove(Key);
EventsMutex.WriteUnlock();
}
else
{
check(Event.IsValid());
Event->Wait();
PipelineMutex.ReadLock();
Desc = Pipelines.FindRef(Key);
PipelineMutex.ReadUnlock();
check(Desc);
}
}`其中的TSharedPtr<FPThreadEvent, ESPMode::ThreadSafe> Event析构时发生Crash
[Image Removed]
看起来像是某种情况这个智能指针的引用计数出现问题了?
还有个信息是:最开始出现Crash的时候有怀疑过是否某个Shader编译导致,后面在GetRenderPipeline方法的开头补了个Log输出编译的ShaderHash,再对应去找到哪个材质。但发现几次Crash的材质都不相同,看起来不像是某个材质出问题导致的。
看起来更像是r.PSOPrecache.Resources这个功能在Metal平台上有问题