getnamo / TCP-Unreal

Convenience TCP wrapper for Unreal Engine
MIT License
108 stars 37 forks source link

Unreal 5.2 : crashes when the level is changed #13

Open ClockworkOwlKR opened 5 months ago

ClockworkOwlKR commented 5 months ago

When current level contains an actor with TCP Server Component, and different level is loaded, the game randomly crashes. Crash is either access violation with random 64bit address, invalid index on the array of clients, or assertion failure that catches array being modified mid-iteration. In almost all of the cases, Stack traces to TCPServerComponent.cpp line 174.

Crash happens regardless of any clients being connected or not. Tried terminating the connection right before level changes on either side. Does not help the issue.

Server connects to a localhost process(it's a jury-rigged solution for large data IPC). The "different level" also has a TCP Server, but tried an empty map and it still crashes, so probably irrelevant.

ClockworkOwlKR commented 5 months ago

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000100000000

VCRUNTIME140 UnrealEditor_TCPWrapper!TMulticastScriptDelegate::ProcessMulticastDelegate() [C:\Program Files\Epic Games\UE_5.2\Engine\Source\Runtime\Core\Public\UObject\ScriptDelegates.h:562] UnrealEditor_Core!TGraphTask::ExecuteTask() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1310] UnrealEditor_Core!FNamedTaskThread::ProcessTasksNamedThread() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:758] UnrealEditor_Core!FNamedTaskThread::ProcessTasksUntilQuit() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:649] UnrealEditor_Core!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2123] UnrealEditor_Engine!FTickTaskSequencer::ReleaseTickGroup() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:556] UnrealEditor_Engine!FTickTaskManager::RunTickGroup() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:1583] UnrealEditor_Engine!UWorld::RunTickGroup() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:770] UnrealEditor_Engine!UWorld::Tick() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:1512] UnrealEditor_UnrealEd!UEditorEngine::Tick() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1905] UnrealEditor_UnrealEd!UUnrealEdEngine::Tick() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:519] UnrealEditor!FEngineLoop::Tick() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5812] UnrealEditor!GuardedMain() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:188] UnrealEditor!GuardedMainWrapper() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:107] UnrealEditor!LaunchWindowsStartup() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:244] UnrealEditor!WinMain() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:284] UnrealEditor!__scrt_common_main_seh() [D:\a_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288] kernel32 ntdll

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff

UnrealEditor_Core!mi_free() [D:\build++UE5\Sync\Engine\Source\ThirdParty\mimalloc\src\alloc.c:486] UnrealEditor_Core!FMallocMimalloc::Realloc() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\MallocMimalloc.cpp:132] UnrealEditor_Core!FMemory::Realloc() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Public\HAL\FMemory.inl:56] UnrealEditor_TCPWrapper!TArray<TSparseArrayElementOrFreeListLink<TAlignedBytes<40,8> >,TSizedDefaultAllocator<32> >::ResizeTo() [C:\Program Files\Epic Games\UE_5.2\Engine\Source\Runtime\Core\Public\Containers\Array.h:2964] UnrealEditor_TCPWrapper!TSparseArray<TSetElement<TTuple<FString,TSharedPtr<FTCPClient,1> > >,TSparseArrayAllocator<TSizedDefaultAllocator<32>,FDefaultBitArrayAllocator> >::Empty() [C:\Program Files\Epic Games\UE_5.2\Engine\Source\Runtime\Core\Public\Containers\SparseArray.h:390] UnrealEditor_TCPWrapper!UE::Core::Private::Function::TFunctionRefCaller<,void __cdecl(void)>::Call() [C:\Program Files\Epic Games\UE_5.2\Engine\Source\Runtime\Core\Public\Templates\Function.h:474] UnrealEditor_Core!TGraphTask::ExecuteTask() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1310] UnrealEditor_Core!FNamedTaskThread::ProcessTasksNamedThread() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:758] UnrealEditor_Core!FNamedTaskThread::ProcessTasksUntilQuit() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:649] UnrealEditor_Core!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete() [D:\build++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2123] UnrealEditor_Engine!FTickTaskSequencer::ReleaseTickGroup() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:556] UnrealEditor_Engine!FTickTaskManager::RunTickGroup() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:1583] UnrealEditor_Engine!UWorld::RunTickGroup() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:770] UnrealEditor_Engine!UWorld::Tick() [D:\build++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:1512] UnrealEditor_UnrealEd!UEditorEngine::Tick() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1905] UnrealEditor_UnrealEd!UUnrealEdEngine::Tick() [D:\build++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:519] UnrealEditor!FEngineLoop::Tick() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5812] UnrealEditor!GuardedMain() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:188] UnrealEditor!GuardedMainWrapper() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:107] UnrealEditor!LaunchWindowsStartup() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:244] UnrealEditor!WinMain() [D:\build++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:284] UnrealEditor!__scrt_common_main_seh() [D:\a_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288] kernel32 ntdll

getnamo commented 5 months ago

Disconnect your TCP before transitioning or attach it to a game instance. It appears your callback returns data after it's owner may have been released. Likely something like: https://github.com/getnamo/TCP-Unreal/blob/master/Source/TCPWrapper/Private/TCPClientComponent.cpp#L114

ClockworkOwlKR commented 5 months ago

The issue has been bypassed by preemptively calling Destroy Actor on the actor 0.5s before the transition happens. It is unclear why does this work but not closing all connections(via blueprint node Disconnect Client : All) or stopping the server(blueprint node Stop Listen Server).

Thanks for the advice. Feel free to close this, or leave it open until fixed if the behavior mentioned above is unintended.