FCCDManagerでクラッシュ(enusure)するが原因が特定できない

お世話になっております。

現在開発中のゲームで、FCCDManagerでenusureに引っかかるようになりました。

ensureはFCCDManagerの288行目にあるものです

// non-dynamic pairs are already ignored in Init() so if Particle 0 is null the second one should not be

ensure(CCDConstraint.Particle[1] != nullptr);

今まではこのenusureに引っかかることはありませんでした。

ですが、こちらのenusureで引っかかること確認されてエラーログを確認したのですが、どの処理からenusureで止まる原因になったのかがわかりません。

どのように対処したらよいかをわからずでして、対応に困っています。

対処方法を教えていただければと思います。

よろしくお願いします。

if (Island == INDEX_NONE)
			{
				// non-dynamic pairs are already ignored in Init() so if Particle 0 is null the second one should not be 
				ensure(CCDConstraint.Particle[1] != nullptr);
 
				if (CCDConstraint.Particle[1])
				{
					Island = CCDConstraint.Particle[1]->Island;
				}	
			}
			CCDConstraint.Island = Island;

コールスタックは下記のようになっております

1711
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp
 
TestGame_Win64_Test!ReportEvent
1751
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformCrashContext.cpp
 
TestGame_Win64_Test!FDebug::EnsureFailed
572
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp
 
TestGame_Win64_Test!FDebug::OptionallyLogFormattedEnsureMessageReturningFalseImpl
711
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp
 
TestGame_Win64_Test!FDebug::OptionallyLogFormattedEnsureMessageReturningFalse
149
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h
 
TestGame_Win64_Test!CheckVerifyImpl
762
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp
 
TestGame_Win64_Test!UE::Assert::Private::ExecCheckImplInternal
787
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp
 
TestGame_Win64_Test!Chaos::FCCDManager::AssignConstraintIslandsAndRecordConstraintNum
288
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/CCDUtilities.cpp
 
TestGame_Win64_Test!Chaos::FCCDManager::ApplySweptConstraints
120
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/CCDUtilities.cpp
 
TestGame_Win64_Test!Chaos::FCCDManager::ApplyConstraintsPhaseCCD
102
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/CCDUtilities.cpp
 
TestGame_Win64_Test!Chaos::FPBDRigidsEvolutionGBF::AdvanceOneTimeStepImpl
563
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolutionGBF.cpp
 
TestGame_Win64_Test!Chaos::FPBDRigidsEvolutionGBF::AdvanceOneTimeStep
365
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolutionGBF.cpp
 
TestGame_Win64_Test!Chaos::AdvanceOneTimeStepTask::DoWork
539
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/PBDRigidsSolver.cpp
 
TestGame_Win64_Test!Chaos::FPBDRigidsSolver::AdvanceSolverBy
1387
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/PBDRigidsSolver.cpp
 
TestGame_Win64_Test!Chaos::FPhysicsSolverAdvanceTask::AdvanceSolver
175
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/Framework/PhysicsSolverBase.cpp
 
TestGame_Win64_Test!Chaos::FPhysicsSolverAdvanceTask::DoTask
151
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/Framework/PhysicsSolverBase.cpp
 
TestGame_Win64_Test!TGraphTask<Chaos::FPhysicsSolverAdvanceTask>::ExecuteTask
1235
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/TaskGraphInterfaces.h
 
TestGame_Win64_Test!FBaseGraphTask::Execute
840
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/TaskGraphInterfaces.h
 
TestGame_Win64_Test!FTaskGraphCompatibilityImplementation::QueueTask::__l5::<lambda_1>::operator()
1970
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Async/TaskGraph.cpp
 
TestGame_Win64_Test!`LowLevelTasks::FTask::Init<`FTaskGraphCompatibilityImplementation::QueueTask'::`5'::<lambda_1> >'::`13'::<lambda_1>::operator()
499
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/Fundamental/Task.h
 
TestGame_Win64_Test!Invoke
47
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Templates/Invoke.h
 
TestGame_Win64_Test!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<`LowLevelTasks::FTask::Init<`FTaskGraphCompatibilityImplementation::QueueTask'::`5'::<lambda_1> >'::`13'::<lambda_1>,0>::Call
162
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/Fundamental/TaskDelegate.h
 
TestGame_Win64_Test!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<`LowLevelTasks::FTask::Init<`FTaskGraphCompatibilityImplementation::QueueTask'::`5'::<lambda_1> >'::`13'::<lambda_1>,0>::CallAndMove
171
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/Fundamental/TaskDelegate.h
 
TestGame_Win64_Test!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::CallAndMove
308
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/Fundamental/TaskDelegate.h
 
TestGame_Win64_Test!LowLevelTasks::FTask::ExecuteTask
627
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Async/Fundamental/Task.h
 
TestGame_Win64_Test!FCpuProfilerTrace::FEventScope::{ctor}
133
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/ProfilingDebugging/CpuProfilerTrace.h
 
TestGame_Win64_Test!LowLevelTasks::FScheduler::ExecuteTask
154
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Async/Fundamental/Scheduler.cpp
 
TestGame_Win64_Test!LowLevelTasks::FScheduler::TryExecuteTaskFrom
362
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Async/Fundamental/Scheduler.cpp
 
TestGame_Win64_Test!LowLevelTasks::FScheduler::WorkerMain
397
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Async/Fundamental/Scheduler.cpp
 
TestGame_Win64_Test!LowLevelTasks::FScheduler::CreateWorker::__l2::<lambda_1>::operator()
70
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Async/Fundamental/Scheduler.cpp
 
TestGame_Win64_Test!Invoke
47
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Templates/Invoke.h
 
TestGame_Win64_Test!UE::Core::Private::Function::TFunctionRefCaller<`LowLevelTasks::FScheduler::CreateWorker'::`2'::<lambda_1>,void __cdecl(void)>::Call
406
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Templates/Function.h
 
TestGame_Win64_Test!UE::Core::Private::Function::TFunctionRefBase<UE::Core::Private::Function::TFunctionStorage<1>,void __cdecl(void)>::operator()
555
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Public/Templates/Function.h
 
TestGame_Win64_Test!FThreadImpl::Run
69
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/HAL/Thread.cpp
 
TestGame_Win64_Test!FRunnableThreadWin::Run
149
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Windows/WindowsRunnableThread.cpp
 
TestGame_Win64_Test!FRunnableThreadWin::GuardedRun
79
C:/projects/build_package/mainline_all/Engine/Source/Runtime/Core/Private/Windows/WindowsRunnableThread.cpp

まずバグデータベースやEPSをしらべましたが同様の情報をみつけることが出来ませんでした。

問題のEnsureはコンストレイントのアイランド番号を確定させるために2つのパーティクルから情報を取得しようとしているところで発生しています。

少なくともどちらか一方のアイランド番号が必要になりますがパーティクルの要素0からは有効なアイランドが取得できず、さらに要素1も非ダイナミックステータスのためかnullになっていてどちらかからもアイランド番号が取れなくなってしまっています。

可能性としては「要素0のポインタは有効だがアイランドが設定されていない」か、「どちらの要素もポインタがnull」になりますが、

まず前者は出会った場合にはAssignParticleIslandsAndGroupParticles関数内での割り当てに問題が発生しており、

後者であればどちらの要素もnullであったならInit関数の以下の条件式によってコンストレイント自体が作られていないはずですがなにか異常な経路があることになります。

			// make sure we ignore pairs that don't include any dynamics
			if (CCDParticlePair[0] != nullptr || CCDParticlePair[1] != nullptr)
			{

条件の絞り込みのためにコンストレイントの状態とそれぞれのパーティクルのステータスをまず確認できればと思いますが再現は可能でしょうか?

お世話になっております。

なかなか再現しないのですが、

こちららで調査してるDumpからコンストレインの状態など確認できるかを深堀りしてみます。

ありがとうございます。

なるほど再現性が低いのですね。

ゲームスレッド側から物理界のパーティクルに干渉して状態を変更するようなコードが含まれている可能性はありますか?

ご返答ありがとうございます。

パーティクル周りの担当に確認してみます。

失礼しました。CCD判定などで扱われているパーティクルは物理界でのシミュレーションの質点でありジオメトリパーティクルと表現するべきでした。

例えばコリジョン付きのプリミティブはFBodyInstaneを持ちますがFBodyInstane::GetPhysicsActorHandle()やFSingleParticlePhysicsProxy::GetPhysicsThreadAPI()と辿ってChaos::FGeometryParticleHandleを取得できます。

これが物理スレッドで処理されるインタンスを示すことになります。

まず物理シミュレーション界でのジオメトリパーティクルの問題なので、Niagaraのパーティクルは全くの別物になりますのでVFX(パーティクル)周りの担当者様は無関係と断言してしまってよいかと思います。

>このensureに関することはUse CCD周りが影響してて、最悪このチェックがついてるものでが何回もHITが入ってタイミングが悪いときにensureに引っかかってる可能性はありますか?

この処理自体がCCDが有効なプリミティブが他の物理表現と接触した時(≒コンストレイントが作られた時)に実行されるものなので、バグの再現率という観点ではヒットし続けていると再現確率は上昇すると思います。

お世話になっております。

こちらのクラッシュに関してですが、未だに改善せず原因のエフェクトなどが見つからない状態です。

現在、Logなどを仕込んでより情報を出せるようにしようとしてますがなかなか再現しないので難航しています。

このままの状態はまずいと思うので、またプライベートでDumpを見てもらいたいと思います。

承知しました。

問題が再現しましたらご連絡いただけますと幸いです。

> 未だに改善せず原因のエフェクトなどが見つからない状態です。

前のコメントで申し上げましたが、物理界のパーティクル=質点と、VFX(Niagara)のパーティクルエフェクトは別ものです。

正しく把握されているなら申し訳ありませんが一度ご確認いただけますでしょうか。

パーティクルなどを担当してるPGに質問してみたところ

ゲームスレッド側から物理界のパーティクルに干渉してるコードは実装してるものは無いとのことです

エンジン側の用意してる仕組みでゲームスレッドでゲーム側の情報を取ってきたりはあるが、ゲーム側からパーティクル側の情報をいじるような処理はしてないとのことです。

ただし、

「Niagara側で使っている物理絡みの挙動はほとんどの場合コリジョントレース程度で、ごく一部にChaosとエフェクトを組み合わせたものがあるという感じです(破壊可能オブジェクト)。」

とのことなので、クラッシュの箇所から怪しいAssetを絞り込んでみようと思います。

すみません、パーティクル周りの担当から下記のような質問がきてるのですが

このあたりよくわからないのですが

「ゲームスレッド側から物理界のパーティクルに干渉して状態を変更するようなコードが含まれている可能性はありますか?」

というものは

「ChaosモジュールにおけるパーティクルとはGeometryCollection内で扱われる破片のことではないでしょうか?

少なくともNiagaraは無関係そうで、以下の質問としてもGeometryCollectionへの操作のことを指すものでよろしいですか」

という質問です。

私は担当が違うのでパーティクルとChaos周りは見てないのでなんとも返答できないのですが指してるものはあっているのでしょうか?

すみません、こちらでパーティクル周りの担当に確認を取ったところ

「Niagaraにはコリジョン(FBodyInstance)を持たせられないのでそもそもCCDManagerとの関わりが考えにくく、原因特定のお役には立てなさそうです。」

とのことで、パーティクル担当者では対処不可でした。

また、Dumpからの情報が追いきれないので他の破壊可能オブジェクトが絡んでるだろうけど、どれが問題になっているのか確認できない状態です。

プライベートに切り替えてDumpを診てもらうことを考えていますので、こちらの許可降り次第お願いしたいと思います。

追加ですみません。

このensureに関することはUse CCD周りが影響してて、最悪このチェックがついてるものでが何回もHITが入ってタイミングが悪いときにensureに引っかかってる可能性はありますか?