ChaosWheeledVehicleMovementComponent.cpp (619)の以下のコードでクラッシュします。
Chaos::FPhysicsSolver* Solver = Proxy->GetSolver<Chaos::FPhysicsSolver>();
Proxyに0xddddddddddddddddが入っていたことからメモリからすでに無くなっていると思われます。調査してみた結果、おそらく以下の理由ではないかと考えられます。
- 何かしらの理由でUChaosWheeledVehicleMovementComponent::OnDestroyPhysicsState()が呼ばれます。
- UChaosWheeledVehicleMovementComponent::OnDestroyPhysicsState()でConstraintHandlesをクリアしています。これによりFPhysicsConstraintReference_Chaos::Constraintのメモリ領域が解放されます。
- UChaosVehicleMovementComponent::VehicleSimulationPT内のConstraintHandlesは解放されたことが伝わっておらず、そのままUChaosWheeledVehicleSimulation::ApplySuspensionForces()で処理されてクラッシュ。
上記の理由から推測して修正を行いました。UChaosWheeledVehicleMovementComponent::OnDestroyPhysicsState()の最後の方にVehicleSimulationPT->UpdateConstraintHandles(ConstraintHandles);を呼び出して、空になったConstraintHandlesを渡したら症状が改善されました。
これらの対応は問題ありませんでしょうか?
何卒宜しくお願い致します。
アクターの破壊などの操作が物理スレッドの動作中に行われているのであれば同期の複雑な問題が発生する可能性があります。
実際にApplySuspensionForcesも物理スレッドの動作タイミングで呼ばれており、OnDestroyPhysicsStateが別スレッド上で同時に処理されたりすると再現性の低いクラッシュバグなどを引き起こす可能性があることにご注意ください。
車両の破壊操作は物理スレッドが動作していないタイミング(TG_PrePhysicsやTG_PostPhysics)で実行することを推奨します。
もし処理タイミングが不適切な可能性があるならば、タイミングを調整して問題が改善するかどうかをご確認ください。
同様のクラッシュを再現できていないことからUpdateConstraintHandlesが確実に問題無い呼び出しかどうかは断言できませんが、上記のような同期の問題がクリアされているのであれば、恐らく関数を呼び出すこと自体には問題はございません。
アクターの破棄については、こちらとしては意図的に破棄してはおらず、配置のミスで落下しつづけており、破棄する高さまで落下して自動的に破棄されていたことが判明しました。
以下UChaosWheeledVehicleMovementComponent::OnDestroyPhysicsState()がコールされるまでの呼び出し履歴です。
`Scone.exe!UChaosWheeledVehicleMovementComponent::OnDestroyPhysicsState() 行 1305 C++
Scone.exe!UActorComponent::DestroyPhysicsState() 行 1796 C++
Scone.exe!UActorComponent::ExecuteUnregisterEvents() 行 1838 C++
Scone.exe!UActorComponent::UnregisterComponent() 行 1561 C++
Scone.exe!AActor::UnregisterAllComponents(bool bForReregister) 行 5466 C++
Scone.exe!UWorld::DestroyActor(AActor * ThisActor, bool bNetForce, bool bShouldModifyLevel) 行 1009 C++
Scone.exe!AActor::Destroy(bool bNetForce, bool bShouldModifyLevel) 行 4848 C++
Scone.exe!AActor::CheckStillInWorld() 行 1902 C++
Scone.exe!UPrimitiveComponent::SyncComponentToRBPhysics() 行 837 C++
[インライン フレーム] Scone.exe!USkeletalMeshComponent::EndPhysicsTickComponent(FSkeletalMeshComponentEndPhysicsTickFunction &) 行 3529 C++
[インライン フレーム] Scone.exe!FSkeletalMeshComponentEndPhysicsTickFunction::ExecuteTick::l2::(float) 行 104 C++
[インライン フレーム] Scone.exe!FActorComponentTickFunction::ExecuteTickHelper(UActorComponent *) 行 4726 C++
Scone.exe!FSkeletalMeshComponentEndPhysicsTickFunction::ExecuteTick(float DeltaTime, ELevelTick TickType, ENamedThreads::Type CurrentThread, const TRefCountPtr & MyCompletionGraphEvent) 行 102 C++
Scone.exe!FTickFunctionTask::DoTask(ENamedThreads::Type CurrentThread, const TRefCountPtr & MyCompletionGraphEvent) 行 307 C++
Scone.exe!TGraphTask::ExecuteTask() 行 636 C++
[インライン フレーム] Scone.exe!UE::Trace::FChannel::operator|(const UE::Trace::FChannel &) 行 29 C++
[インライン フレーム] Scone.exe!TaskTrace::FTaskTimingEventScope::{ctor}(unsigned int64) 行 301 C++
Scone.exe!UE::Tasks::Private::FTaskBase::TryExecuteTask() 行 505 C++
[インライン フレーム] Scone.exe!FBaseGraphTask::Execute(TArray<FBaseGraphTask *,TSizedDefaultAllocator<32>> &) 行 482 C++
Scone.exe!FNamedTaskThread::ProcessTasksNamedThread(int QueueIndex, bool bAllowStall) 行 779 C++
Scone.exe!FNamedTaskThread::ProcessTasksUntilQuit(int QueueIndex) 行 668 C++
[インライン フレーム] Scone.exe!FTaskGraphCompatibilityImplementation::ProcessThreadUntilRequestReturn(ENamedThreads::Type) 行 1453 C++
Scone.exe!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete(const TArray<TRefCountPtr,TSizedInlineAllocator<4,32,TSizedDefaultAllocator<32>>> & Tasks, ENamedThreads::Type CurrentThreadIfKnown) 行 1526 C++
Scone.exe!FTickTaskSequencer::ReleaseTickGroup(ETickingGroup WorldTickGroup, bool bBlockTillComplete) 行 815 C++
Scone.exe!FTickTaskManager::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) 行 1866 C++
Scone.exe!UWorld::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) 行 775 C++
Scone.exe!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) 行 1531 C++
Scone.exe!UGameEngine::Tick(float DeltaSeconds, bool bIdleMode) 行 1784 C++
Scone.exe!FEngineLoop::Tick() 行 5877 C++
[インライン フレーム] Scone.exe!EngineTick() 行 69 C++
Scone.exe!GuardedMain(const wchar_t * CmdLine) 行 188 C++
Scone.exe!GuardedMainWrapper(const wchar_t * CmdLine) 行 123 C++
Scone.exe!LaunchWindowsStartup(HINSTANCE * hInInstance, HINSTANCE * hPrevInstance, char * formal, int nCmdShow, const wchar_t * CmdLine) 行 277 C++
Scone.exe!WinMain(HINSTANCE * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) 行 318 C++`なのでUnreal Engineのライブラリ側でこの問題を対処していただく必要があるかと思いますが、いかがでしょうか?
またこの現象が起きたアクターは、御社が提供されているトラック等をそのまま使用したものとなっています。
何卒宜しくお願い致します。
ご調査ありがとうございます。実際にVehicleテンプレートをベースにしてプロジェクトを作成し、場外で車両を生成してKillZで頂戴したコールスタックの場所でアクターが破棄されることを確認できました。しかし、この操作がクラッシュにつながっておりません。
是非再現させてバグ登録したいのですが、車両を生成してKillZでアクターを破壊する以外に再現に必要な条件についてお気づきの点がございますか?
大変申し訳ありません。
問題のトラックについては仕様上無くなってしまい、また弊社でも同じ状況を再現しようとしたのですが再現できませんでした。
よく調べてみたら理解できたのですが、
UChaosVehicleMovementComponent::ConstraintHandles と UChaosVehicleMovementComponent::VehicleSimulationPT 内の ConstraintHandles の内容は本来全く同じになるはずなので、なぜこうのようなクラッシュが起きたのか、原因がつかめておりません。
この問題についてはまた再現されたら改めて報告させてください。
お手数をお掛けして申し訳ありません。何卒宜しくお願い致します。
再現が難しい状態になっている件承知しました。もし再現に至った場合にはご一報いただけますと幸いです。