Hi,
Describe the bug
FGSDKInternal::SendHeartbeat() may crash after the engine's shutdown phase.
Because this happens in async code, this does not always occur, depending on timings.
The crash occurs due to a nullptr dereference at the line FHttpModule::Get().CreateRequest() in FGSDKInternal::SendHeartbeat(), after the engine's shutdown phase (when the game server requests exits and all modules are unloaded).
The only way this could happen would be because the HTTP module is unloaded, and because we're in the shutdown phase, the module is not allowed to be loaded again.
To prevent this, the following snippet could be inserted at the beginning of FGSDKInternal::SendHeartbeat():
if (!FModuleManager::Get().IsModuleLoaded(TEXT("HTTP")))
return;
However, it would still not be thread-safe: it's technically possible for the HTTP module to be unloaded on the GameThread at the exact same time it is accessed from the async thread.
To Reproduce
- Run any dedicated server built with Unreal Engine and the PlayFab GSDK; For this, use PlayFab's
LocalMultiplayerAgent tool.
- Make the server exit normally (one way to do this is
FGenericPlatformMisc::RequestExit(false))
- The aforementioned crash may occur because
FHttpModule::Get() returns nullptr.
Hi,
Describe the bug
FGSDKInternal::SendHeartbeat()may crash after the engine's shutdown phase.Because this happens in async code, this does not always occur, depending on timings.
The crash occurs due to a nullptr dereference at the line
FHttpModule::Get().CreateRequest()inFGSDKInternal::SendHeartbeat(), after the engine's shutdown phase (when the game server requests exits and all modules are unloaded).The only way this could happen would be because the HTTP module is unloaded, and because we're in the shutdown phase, the module is not allowed to be loaded again.
To prevent this, the following snippet could be inserted at the beginning of
FGSDKInternal::SendHeartbeat():However, it would still not be thread-safe: it's technically possible for the HTTP module to be unloaded on the GameThread at the exact same time it is accessed from the async thread.
To Reproduce
LocalMultiplayerAgenttool.FGenericPlatformMisc::RequestExit(false))FHttpModule::Get()returnsnullptr.