アプリケーション終了時にOnlineServicesOSSAdapterでクラッシュする

Steam版でパッケージングしたアプリケーションを終了するときにクラッシュします。

FAuthOSSAdapter::GetIdentityInterface()内でクラッシュしており、OnlineServicesOSSAdapterよりもOnlineSubsystemSteamが先にアンロードされているため発生しております。

以下のスレッドの質問内容と同じです。しかし修正対応として挙げられているCL#34375152はエディタで発生するクラッシュの修正ですが、今回の質問のクラッシュはパッケージで発生しているため別の問題のようです。

[Content removed]

対処方法をご教授して頂けますでしょうか。

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

こちらについてはクラッシュ時のコールスタックがございましたらご共有頂けますと幸いです。

以下コールスタックです。ご確認よろしくお願いいたします。

RtlpWaitOnCriticalSection()

RtlpEnterCriticalSectionContended()

RtlEnterCriticalSection()

Windows::EnterCriticalSection(Windows::CRITICAL_SECTION *) 行 238 C++

UE::FWindowsRecursiveMutex::Lock() 行 45 C++

UE::TScopeLock<UE::FWindowsRecursiveMutex>::{ctor}(UE::FWindowsRecursiveMutex &) 行 28 C++

TDelegateAccessHandlerBase<FThreadSafeDelegateMode>::GetWriteAccessScope() 行 86 C++

TMulticastDelegateBase<FDefaultTSDelegateUserPolicy>::Broadcast<IBaseDelegateInstance<void __cdecl(void),FDefaultTSDelegateUserPolicy>>() 行 247 C++

TMulticastDelegate<void __cdecl(void),FDefaultTSDelegateUserPolicy>::Broadcast() 行 1080 C++

FWindowsPlatformMisc::RequestExitWithStatus(bool) 行 1371 C++

FWindowsPlatformMisc::RequestExit(bool Force, const wchar_t * CallSite) 行 1345 C++

AbortHandler(int Signal) 行 1179 C++

[外部コード]

UE::Online::FAuthOSSAdapter::GetIdentityInterface() 行 585 C++

UE::Online::FAuthOSSAdapter::PreShutdown() 行 167 C++

Invoke(void(UE::Online::IOnlineComponent::*)()) 行 66 C++

UE::Online::FOnlineComponentRegistry::Visit(void(UE::Online::IOnlineComponent::*)() &&) 行 78 C++

UE::Online::FOnlineServicesCommon::PreShutdown() 行 250 C++

UE::Online::FOnlineServicesCommon::Destroy() 行 117 C++

UE::Online::FOnlineServicesRegistry::~FOnlineServicesRegistry() 行 213 C++

[外部コード]

FCrashReportingThread::Run() 行 1282 C++

[外部コード]

お世話になっております。ご返答が遅くなりまして申し訳ございません。このクラッシュは主にアプリケーション終了時のオンラインサービスシャットダウン処理でデッドロックが発生していることが原因です。特にTMulticastDelegateのブロードキャスト処理とミューテックスロックの競合が問題となっています。最も効果的な対策は、オンラインサービスのシャットダウン処理を非同期化し、デリゲートシステムの同期処理を見直すことです。また、デバッグのためにログを追加して、どの段階でデッドロックが発生しているかを特定することをお勧めします。というご提案をさせて頂いたのですが、残念ながら今のところこのような問題が修正が行われた情報などが見つかっておらず、AuthOSSAdapterを介してのコールスタックのケースは、ご報告頂いたケースのみとなっておりました。こちらに関して、御社側で何かカスタマイズを行ったりされている個所が影響を及ぼしていないか、に関してはご検討いただけますと幸いです。

頂いた情報を元にカスタマイズ部分等、調査したのですがクラッシュの原因箇所が特定できておりません。しかしながら、OnlineServicesOSSAdapterのLoadingPhaseをPostConfigInitからDefaultに変更することでクラッシュの回避ができることが分かっております。この変更につきまして、何かリスクが考えられましたらお聞かせ頂けないでしょうか。よろしくお願いいたします。

お世話になっております。現在判明している回避策をお知らせ頂きありがとうございます。LoadingPhaseを変更することについてのリスクを分析すると、まず初期化順序が変わるということが発生します。今回該当するのが以下の内容です。

PostConfigInit: コンソール変数などが既に初期化済みのタイミングで読み込まれる

Default: 他のモジュールと同時期に読み込まれるため、依存先の初期化完了を前提にできない

OnlineServices関連がすべてPostConfigInitになっているため一貫性の問題もありますが、コンソール変数や設定へのアクセスで未初期化状態に遭遇する可能性はあり、この場合オンラインサービス初期化が失敗することが想定されますが、特にサービス初期化の問題に遭遇していない場合は順番に影響は及ぼされていません。

Defaultに変更することで回避できる理由を推測すると、読み込み順が変わることでデッドロックを回避できているか、シャットダウン時の破壊順序が変わり、競合を避けることが出来ていることが想定されます(この場合アプリケーション終了時のため、後者で回避できていることが想定されます)。もしこの変更が作用して問題が回避できている場合、OSSAdapterの初期化処理を確認しておくことをおすすめします。LoadingPhaseはPostConfigInitのままとする場合は、モジュールの破棄タイミングでの競合するモジュールを確認して頂くか、シャットダウン処理における破棄の排他処理を追加することが必要になるかと思われます。

ご回答ありがとうございます。リスクにつきまして諸々承知いたしました。留意しつつ進めてまいります。​

ご対応いただきありがとうございました。