Access Violation when adding UserWidget to Viewport

Hi everybody!

I make plugin for my project on C++ and trying to add some GUI wrapper.

So, i preload widget classes on creating actor and i try to create widgets from them on demand. And i got this exception on adding created widget from viewport:

LoginId:ed13a746455d7189d177a6918468c7bd
EpicAccountId:bdacb06325334985a2acfedc7ba6237f

Access violation - code c0000005 (first/second chance not available)

UE4Editor_UMG!UUserWidget::RebuildWidget() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\umg\private\userwidget.cpp:800]
UE4Editor_UMG!UWidget::TakeWidget_Private() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\umg\private\components\widget.cpp:678]
UE4Editor_UMG!UWidget::TakeWidget() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\umg\private\components\widget.cpp:665]
UE4Editor_UMG!UUserWidget::AddToScreen() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\umg\private\userwidget.cpp:972]
UE4Editor_AssistCorePlugin!AGUI::Show() [d:\repos\districts\districts-game\plugins\assistcoreplugin\source\assistcoreplugin\private\gui.cpp:92]
UE4Editor_AssistCorePlugin!AGUI::execShow() [d:\repos\districts\districts-game\plugins\assistcoreplugin\source\assistcoreplugin\public\gui.h:17]
UE4Editor_CoreUObject!UFunction::Invoke() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4542]
UE4Editor_CoreUObject!UObject::CallFunction() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:732]
UE4Editor_CoreUObject!UObject::ProcessContextOpcode() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:2167]
UE4Editor_CoreUObject!UObject::ProcessInternal() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:954]
UE4Editor_CoreUObject!UObject::CallFunction() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:856]
UE4Editor_CoreUObject!UObject::ProcessInternal() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:954]
UE4Editor_CoreUObject!UFunction::Invoke() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4542]
UE4Editor_CoreUObject!UObject::ProcessEvent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:1314]
UE4Editor_Engine!AActor::ProcessEvent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\actor.cpp:693]
UE4Editor_Engine!AActor::BeginPlay() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\actor.cpp:3192]
UE4Editor_Engine!AActor::DispatchBeginPlay() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\actor.cpp:3160]
UE4Editor_Engine!AWorldSettings::NotifyBeginPlay() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\worldsettings.cpp:187]
UE4Editor_Engine!AGameStateBase::HandleBeginPlay() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\gamestatebase.cpp:177]
UE4Editor_Engine!UWorld::BeginPlay() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\world.cpp:3505]
UE4Editor_Engine!UGameInstance::StartPlayInEditorGameInstance() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\gameinstance.cpp:355]
UE4Editor_UnrealEd!UEditorEngine::CreatePIEGameInstance() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\playlevel.cpp:3273]
UE4Editor_UnrealEd!UEditorEngine::PlayInEditor() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\playlevel.cpp:2409]
UE4Editor_UnrealEd!UEditorEngine::StartQueuedPlayMapRequest() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\playlevel.cpp:1270]
UE4Editor_UnrealEd!UEditorEngine::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\editorengine.cpp:1558]
UE4Editor_UnrealEd!UUnrealEdEngine::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\unrealedengine.cpp:396]
UE4Editor!FEngineLoop::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:3296]
UE4Editor!GuardedMain() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\launch.cpp:166]
UE4Editor!GuardedMainWrapper() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
UE4Editor!WinMain() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:210]
UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253]
kernel32
ntdll

This is Constructor, where i preload my widget classes

AGUI::AGUI()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	TArray<UGUIFrameDBItem*> FramesItems = DBLoader::GetItems<UGUIFrameDBItem>();
	for (UGUIFrameDBItem* FrameItem : FramesItems)
	{
		DBLoader::LoadBPClass(FrameItem, FString(TEXT("Frame")));
		static ConstructorHelpers::FClassFinder<UGUIFrame> mainMenuWidgetClassFinder(*FrameItem->GetWidgetClassPath());
		if (mainMenuWidgetClassFinder.Succeeded())
		{
			UE_LOG(LogTemp, Warning, TEXT("Class for frame %s preloaded [%s]"), *FrameItem->GetName(), *((UClass*)mainMenuWidgetClassFinder.Class)->GetFullName());
			FramesClasses.Add(FrameItem, (UClass*)mainMenuWidgetClassFinder.Class);
		}
	}

	UE_LOG(LogTemp, Warning, TEXT("GUI Created [%d frames classes preloaded]"), FramesClasses.Num());
}

And this is my method Show called on showing widget

void AGUI::Show(UGUIFrameDBItem * FrameItem)
{
	if (AssistGameInstance == nullptr || AssistGameInstance == NULL)
	{
		UE_LOG(LogTemp, Error, TEXT("Game instance not initialized yet"));
		return;
	}

	if (CurrentFrameDBItem == FrameItem)
	{
		UE_LOG(LogTemp, Warning, TEXT("Frame %s already showed"), *FrameItem->GetName());
		return;
	}

	if (!FramesClasses.Contains(FrameItem) || FramesClasses[FrameItem] == nullptr || FramesClasses[FrameItem] == NULL)
	{
		UE_LOG(LogTemp, Error, TEXT("Frame %s not preloaded"), *FrameItem->GetName());
		return;
	}

	if (CurrentFrame != nullptr && CurrentFrame != NULL)
	{
		CurrentFrame->RemoveFromParent();
	}

	if (FramesPool.Contains(FrameItem))
	{
		UE_LOG(LogTemp, Warning, TEXT("Frame %s already created"), *FrameItem->GetName());
		CurrentFrame = FramesPool[FrameItem];
	}
	else
	{
		CurrentFrame = CreateWidget<UGUIFrame>(AssistGameInstance, FramesClasses[FrameItem]);
		CurrentFrameDBItem = FrameItem;
		UE_LOG(LogTemp, Log, TEXT("Frame %s created"), *CurrentFrame->GetName());
	}

	if (FrameItem->StackIt)
	{
		FramesStack.Enqueue(FrameItem);
	}

	if (CurrentFrame == nullptr || CurrentFrame == NULL)
	{
		UE_LOG(LogTemp, Error, TEXT("Frame %s doesnt created"), *FrameItem->GetName())
	}

	CurrentFrame->AddToViewport();
}

What i did wrong?

Access Valuation means attempt to access unallocated memory, like trying to call function on null pointer or invalid pointer. Stack suggest that it happens inside UGUIFrame, but since it appers as UWidget and UUserWidget it means it happens on non-overrided function. RebuildWidget() is function that builds State widget (UMG it self is wrapper of Slate for blueprints because Slate is not visible in Ue4 reflection system, which is required to be operated in blueprints).

My wild guess is whatever lands in to CurrentFrame varable which calls AddToViewport been garbage collected, this happens when you dont use UPROPERTY() on varable containing the pointer to object. If you don’t use UPROPERTY() UE4 don’t see that varable, it does not know the state of pointer, because of that it does not know the object that it points to is still reference inside AGUI, because of that it assumes it is not used and considered garbage and deletes it from memory. By that your pointer becomes invalid (CurrentFrame == nullptr will return false in this case because pointer is not null, it still pointing to something) and points to unallocated or trash memory. If pointer is indeed pointing to trash, CPU will still execute class code for that object, which in most cases will cause crash as soon as it hits unallocated memory (other invalid pointer in that trash data) thats why it gets deeper in to UWidget code, but might return some wierd things if it manages to return.

Invalid pointer is hard to deal with because CPU don’t have function to check if memory address is valid or not, thats why all object pointers should be nulled when something gets deleted, and thats what UE4 is doing… as long you use UPROPERTY() for it to see your varable.

UObjects have IsValidLowLevel and IsValidLowLevelFast functions which checks if memory address of the pointer (which inside class becomes “this”) points to is inside list of UObject that engine tracks, it heavy operation so it should not be used in ticks etc. where you have limited time of execution. The fast version do some extra checks which might end validation faster before attempting to do heavy list check. You can do this with CurrentFrame to check if it’s indeed invalid. Typical symptom of crash due to invalid pointer made by garbage collection is fact that it happens after specific amount of time when garbage collection happens over time.

1 Like

Wow, I was having tons of issues with Access Violations, UGameInstance::GetFirstLocalPlayerController() was causing an access violation on a pointer that looked like a debug pointer (0xCDCDCDCDCD…) And even just checking if (GEngine == nullptr) was causing an access violation. Then I added some UPROPERTY() to my UUserWidget members in my GameInstance and now no more crashes!

Thank you ! You made my day.

Just wanted to add an additional thing here as I had this problem and was using UPROPERTY appropriately. I was overriding the Initialize virtual function provided by UUserWidget and forgot to call Super::Initialize inside the overidden functions body. Gave me this same error.

Thank you so much! I had the same issue, and after nearly a day of searching, I discovered that I was in the same situation as you. Turns out you gotta remember to call the parent’s function when you override