I’m developing a system that can load in custom .pak files with help of the Pak Loader plugin. I followed the Pak Loader plugin documentation and I able to load in the pak file in game build. But when I try to spawn a blueprint that inside of the pak file the game crashes with the error:
Error: === Critical error: ===
Error: Fatal error!
Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000030
Error: [Callstack] 0x00007ff7c4239af7 AssetStreamerProject-Win64-DebugGame.exe!UWorld::SpawnActor() []
Error: [Callstack] 0x00007ff7c423b6ae AssetStreamerProject-Win64-DebugGame.exe!UWorld::SpawnActor() []
Error: [Callstack] 0x00007ff7bdc298e5 AssetStreamerProject-Win64-DebugGame.exe!UPakContainer::LoadBaseBlueprint()
When I check the minidump of the crash or attach Visual Studio I can see that the crash occurs when the game code calls the GetWorld()->SpawnActor()
method. After that I can’t see where the code crashes in the Unreal Engine source code. I have tried to add the .pdb files to symbol list in Visual Studio 2022 but it doesn’t help. When I call the SpawnActor in an editor build I can see that the SpawnActor method is called in the LevelActor.cpp, but when I place a break point there and debug attach Visual Studio to the 64-bit debug build it will not trigger the breakpoint there because Visual Studio can’t find the symbols there.
There reason for making full game build is because the cooked pak files can’t be opened in a Editor build. Thus when I start the binary from Visual Studio trough the “Local Windows Debugger” play button the game will not load the .pak file correly. And I’m not able use it for debugging in the LevelActor.cpp source code file.
Because I can’t proper debug what is causing the crash, I’m able to figure out what I’m doing wrong. I suspect that either the content of the pak is not correctly register or the pak file itself is not build correctly.
The sample of the code:
Header:
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "PakLoader/Public/PakLoader.h"
#include "PakContainer.generated.h"
ASSETSTREAMER_API DECLARE_LOG_CATEGORY_EXTERN(PakContainerLog, Log, All);
UENUM()
enum EPakLoadingStatus
{
NotLoaded,
LoadError,
NeedsDownloading,
Downloading,
CanBeMounted,
Mounting,
Mounted,
UnMounting,
};
UENUM()
enum EPakFileType
{
Local,
Streaming
};
UCLASS()
class ASSETSTREAMER_API UPakContainer : public UObject
{
GENERATED_BODY()
public:
UPakContainer();
private:
FPakLoader* PakLoader;
FString PakFileName;
FString PakFolderPath;
FString PakMountPath;
FString RootPath;
EPakLoadingStatus LoadingStatus;
EPakFileType PakFileType;
TArray<FString> AssetList;
public:
void InitLocalPakContainer(FString& NewPakFileName, FString& NewPakFolderPath);
void LoadPakFile();
void LoadBaseBlueprint();
FString GetFileName();
private:
};
CPP:
void UPakContainer::LoadPakFile()
{
checkf(PakLoader, TEXT("The PakLoader is not loaded."))
if (LoadingStatus != CanBeMounted)
{
LoadingStatus = LoadError;
return;
}
LoadingStatus = Mounting;
PakMountPath = FPaths::Combine(PakFolderPath, PakFileName);
TRefCountPtr<FPakFile> PakFile =
new FPakFile(PakLoader->GetPakPlatformFile(), *PakMountPath, false);
FPakFile* Pak = PakFile.GetReference();
if (!Pak->IsValid())
{
PakFile.SafeRelease();
LoadingStatus = LoadError;
return;
}
FString ContentPath;
if (!PakLoader->GetRootPathAndContentPathForPak(*Pak, RootPath, ContentPath))
{
PakFile.SafeRelease();
LoadingStatus = LoadError;
return;
}
const FString EmptyMP;
if (!PakLoader->MountPakFile(PakMountPath, INDEX_NONE, EmptyMP))
{
PakFile.SafeRelease();
LoadingStatus = LoadError;
return;
}
PakLoader->RegisterMountPoint(RootPath, ContentPath);
TArray<FString> Files;
Pak->FindPrunedFilesAtPath(Files, *Pak->GetMountPoint(), true, false, true);
FString AssetRegistryFile;
for (const FString& File : Files)
{
if (File.EndsWith("/AssetRegistry.bin", ESearchCase::CaseSensitive))
{
AssetRegistryFile = File;
break;
}
}
PakLoader->LoadAssetRegistryFile(AssetRegistryFile);
PakFile.SafeRelease();
bool Archive = false;
GConfig->GetBool(
TEXT("/Script/UnrealEd.ProjectPackagingSettings"), TEXT("bShareMaterialShaderCode"), Archive, GGameIni);
const bool Enable = !FPlatformProperties::IsServerOnly() && FApp::CanEverRender() && Archive;
if (Enable)
{
FShaderCodeLibrary::OpenLibrary(FApp::GetProjectName(), ContentPath);
}
LoadingStatus = Mounted;
}
void UPakContainer::LoadBaseBlueprint()
{
checkf(PakLoader, TEXT("The PakLoader is not loaded."))
if (LoadingStatus != Mounted)
{
LoadingStatus = LoadError;
return;
}
FString BaseBlueprintPath = FPaths::Combine(RootPath, TEXT("Blueprints/Bouwkunding_model_-_V6"));
UClass* BlueprintClass = PakLoader->LoadClassFromPak(BaseBlueprintPath);
if (!IsValid(BlueprintClass))
{
LoadingStatus = LoadError;
return;
}
FActorSpawnParameters SpawnParameters;
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
GetWorld()->SpawnActor(BlueprintClass->StaticClass(), nullptr, nullptr, SpawnParameters);
}
After couple of day’s of struggling with this I’m out ideas and options on how to fix this issue. If any body could give any suggestions or tips that would create help.
Here list of found potential solutions I have tried but did not work for me:
- Turn off “Async Loading Thread Enabled”
- Starting the game with -fullcrashdumpalways argument. This did make full memory dump but this did give any more call stack information than the standard one. (Did not expected this eater but if don’t try you don’t know.)
- Adding the Debug symbols or pdb folder at “…\UE_5.0\Engine\Binaries\Win64” to the Visual Studio debug symbols list.