Description

If a user-defined struct-type variable is declared in one Blueprint, and that variable is then indirectly accessed in a second Blueprint through a reference to the first Blueprint, modifying the struct after loading both Blueprints may lead to a crash. See attached image for reference.

This occurs because variable nodes don't currently consider the struct type to be an external dependency. As a result, it won't be included in the Blueprint's cached dependency set (specifically cached UDS dependencies), and we won't clear references to the struct prior to recompiling it. These references then become stale in previously-compiled Blueprint function script, which can lead to a crash during bytecode fixup serialization.

Steps to Reproduce
  1. Launch QAGame editor.
  2. Create a new user-defined struct asset (MyUDS), save.
  3. Create a new Actor-based Blueprint (MyBP1) and open it in the BP editor.
  4. Add a new variable of type MyUDS (NewVar_0).
  5. Compile and save MyBP1, close the BP editor.
  6. Create another Actor-based Blueprint (MyBP2) and open it in the BP editor.
  7. Add a new variable of type MyBP1 (NewVar_1).
  8. Drag the variable into the event graph to add a "Get" node for 'NewVar_1'.
  9. Drag off the output pin and add another "Get" node for MyBP1's 'NewVar_0'.
  10. Right-click on the output pin and choose "Split Struct pins."
  11. Drag off the BeginPlay event and add a PrintString node.
  12. Wire the first struct member output pin to the PrintString node.
  13. Compile and save MyBP2, close the BP editor.
  14. Double-click MyUDS to open it in the user-defined struct editor.
  15. Add a new member.
  16. Click the arrows to reorder the members in the struct. Keep swapping member positions and eventually the editor should crash with a similar callstack to what's shown.
    Note: The top of the callstack may vary as it basically depends on the contents of memory as UDS struct fields are invalidated.
Callstack

> UE4Editor-CoreUObject-Win64-Debug.dll!CastChecked<UField,UObject>(UObject * Src) Line 259 C++
UE4Editor-CoreUObject-Win64-Debug.dll!FField::GetOwnerUField() Line 417 C++
UE4Editor-CoreUObject-Win64-Debug.dll!FField::GetOwnerClass() Line 379 C++
UE4Editor-Kismet-Win64-Debug.dll!FBlueprintCompilationManagerImpl::FFixupBytecodeReferences::operator<<(FField * & Field) Line 2977 C++
UE4Editor-CoreUObject-Win64-Debug.dll!FPropertyProxyArchive::operator<<(FField * & Value) Line 46 C++
UE4Editor-CoreUObject-Win64-Debug.dll!UStruct::SerializeExpr(int & iCode, FArchive & Ar) Line 202 C++
UE4Editor-CoreUObject-Win64-Debug.dll!UStruct::SerializeExpr(int & iCode, FArchive & Ar) Line 293 C++
UE4Editor-CoreUObject-Win64-Debug.dll!UStruct::SerializeExpr(int & iCode, FArchive & Ar) Line 192 C++
UE4Editor-CoreUObject-Win64-Debug.dll!UStruct::Serialize(FArchive & Ar) Line 1963 C++
UE4Editor-CoreUObject-Win64-Debug.dll!UFunction::Serialize(FArchive & Ar) Line 5617 C++
UE4Editor-Kismet-Win64-Debug.dll!FBlueprintCompilationManagerImpl::FFixupBytecodeReferences::FFixupBytecodeReferences(UObject * InObject) Line 2904 C++
UE4Editor-Kismet-Win64-Debug.dll!FBlueprintCompilationManagerImpl::FlushCompilationQueueImpl(bool bSuppressBroadcastCompiled, TArray<UBlueprint *,TSizedDefaultAllocator<32>> * BlueprintsCompiled, TArray<UBlueprint *,TSizedDefaultAllocator<32>> * BlueprintsCompiledOrSkeletonCompiled, FUObjectSerializeContext * InLoadContext) Line 1524 C++
UE4Editor-Kismet-Win64-Debug.dll!FBlueprintCompilationManagerImpl::CompileSynchronouslyImpl(const FBPCompileRequestInternal & Request) Line 277 C++
UE4Editor-Kismet-Win64-Debug.dll!FBlueprintCompilationManager::CompileSynchronously(const FBPCompileRequest & Request) Line 3090 C++
UE4Editor-UnrealEd-Win64-Debug.dll!FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(UBlueprint * Blueprint) Line 2074 C++
UE4Editor-KismetCompiler-Win64-Debug.dll!FUserDefinedStructureCompilerUtils::CompileStruct(UUserDefinedStruct * Struct, FCompilerResultsLog & MessageLog, bool bForceRecompile) Line 534 C++
UE4Editor-KismetCompiler-Win64-Debug.dll!FKismet2CompilerModule::CompileStructure(UUserDefinedStruct * Struct, FCompilerResultsLog & Results) Line 86 C++
UE4Editor-UnrealEd-Win64-Debug.dll!FStructureEditorUtils::CompileStructure(UUserDefinedStruct * Struct) Line 544 C++
UE4Editor-UnrealEd-Win64-Debug.dll!FStructureEditorUtils::OnStructureChanged(UUserDefinedStruct * Struct, FStructureEditorUtils::EStructureEditorChangeInfo ChangeReason) Line 556 C++
UE4Editor-UnrealEd-Win64-Debug.dll!FStructureEditorUtils::AddVariable(UUserDefinedStruct * Struct, const FEdGraphPinType & VarType) Line 318 C++
UE4Editor-Kismet-Win64-Debug.dll!FUserDefinedStructureLayout::OnAddNewField() Line 465 C++
UE4Editor-Kismet-Win64-Debug.dll!UE4Tuple_Private::TTupleBase<TIntegerSequence<unsigned int>>::ApplyAfter<FReply (__cdecl FUserDefinedStructureLayout::const &)(void),FUserDefinedStructureLayout * &>(FReply(FUserDefinedStructureLayout::)() & Func, FUserDefinedStructureLayout * & <Args_0>) Line 299 C++
UE4Editor-Kismet-Win64-Debug.dll!TBaseSPMethodDelegateInstance<0,FUserDefinedStructureLayout,0,FReply __cdecl(void),FDefaultDelegateUserPolicy>::Execute() Line 290 C++
UE4Editor-Slate-Win64-Debug.dll!SButton::ExecuteOnClick() Line 385 C++
UE4Editor-Slate-Win64-Debug.dll!SButton::OnMouseButtonUp(const FGeometry & MyGeometry, const FPointerEvent & MouseEvent) Line 304 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::RoutePointerUpEvent::__l8::<lambda>(const FArrangedWidget & TargetWidget, const FPointerEvent & Event) Line 4829 C++
UE4Editor-Slate-Win64-Debug.dll!FEventRouter::Route<FReply,FEventRouter::FToLeafmostPolicy,FPointerEvent,FReply <lambda>(const FArrangedWidget &, const FPointerEvent &)>(FSlateApplication * ThisApplication, FEventRouter::FToLeafmostPolicy RoutingPolicy, FPointerEvent EventCopy, const FSlateApplication::RoutePointerUpEvent::__l8::FReply <lambda>(const FArrangedWidget &, const FPointerEvent &) & Lambda, ESlateDebuggingInputEvent DebuggingInputEvent) Line 378 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::RoutePointerUpEvent(const FWidgetPath & WidgetsUnderPointer, const FPointerEvent & PointerEvent) Line 4815 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::ProcessMouseButtonUpEvent(const FPointerEvent & MouseEvent) Line 5356 C++
UE4Editor-Slate-Win64-Debug.dll!FSlateApplication::OnMouseUp(const EMouseButtons::Type Button, const FVector2D CursorPos) Line 5321 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::ProcessDeferredMessage(const FDeferredWindowsMessage & DeferredMessage) Line 2178 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::DeferMessage(TSharedPtr<FWindowsWindow,0> & NativeWindow, HWND__ * InHWnd, unsigned int InMessage, unsigned __int64 InWParam, __int64 InLParam, int MouseX, int MouseY, unsigned int RawInputFlags) Line 2642 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::ProcessMessage(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 1048 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsApplication::AppWndProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wParam, __int64 lParam) Line 877 C++
[External Code]
UE4Editor-ApplicationCore-Win64-Debug.dll!WinPumpMessages() Line 109 C++
UE4Editor-ApplicationCore-Win64-Debug.dll!FWindowsPlatformApplicationMisc::PumpMessages(bool bFromMainLoop) Line 133 C++
UE4Editor-Win64-Debug.exe!FEngineLoop::Tick() Line 4748 C++
UE4Editor-Win64-Debug.exe!EngineTick() Line 63 C++
UE4Editor-Win64-Debug.exe!GuardedMain(const wchar_t * CmdLine) Line 172 C++
UE4Editor-Win64-Debug.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 257 C++

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-115373 in the post.

0
Login to Vote

Fixed
ComponentUE - Gameplay - Blueprint Editor
Affects Versions4.254.264.26.2
Target Fix4.27
Fix Commit16308198
Release Commit16308211
CreatedMay 11, 2021
ResolvedMay 12, 2021
UpdatedJan 12, 2022