Skip to content

Access violation at startup — ConstructorHelpers in CDOs vs. the PostConfigInit loading phase #9865

Description

@M-Colley

Describe the bug

Adding the Carla plugin to any project whose startup ordering differs from
CarlaUnreal's kills the process before a map is ever opened:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x120
  ATrafficLightManager::ATrafficLightManager()
  ConstructorHelpers::FClassFinder<AActor>::FClassFinder<AActor>()
  StaticLoadClass() -> LoadPackage() -> FlushAsyncLoading()
  FLinkerLoad::CreateExport()
  FBlueprintCompilationManager::FlushCompilationQueue()
  UE::ProjectUtilities::FindModuleDescriptorHostType()
  FModuleManager::LoadModule()
  FLiveCodingModule::StartupModule()          <-- faults here
  UClass::CreateDefaultObject()
  UObjectLoadAllCompiledInDefaultProperties()
  ProcessNewlyLoadedUObjects()
  FEngineLoop::PreInitPostStartupScreen()

Cause

Carla.uplugin sets "LoadingPhase": "PostConfigInit", which it must: the
module registers global shaders (IMPLEMENT_SHADER_TYPE in
Util/CameraModelUtil.cpp) and those have to exist before the engine
initialises shader types — moving the module to Default instead trips
Assertion failed: !AreShaderTypesInitialized().

But that same phase means every CDO in the module is constructed inside
FEngineLoop::PreInitPostStartupScreen, and several of those constructors load
/Game/ packages:

file what it loads
Traffic/TrafficLightManager.cpp 14 FClassFinders (traffic lights, stop/yield/speed-limit signs)
Commandlet/LoadAssetMaterialsCommandlet.cpp RoadPainterPreset blueprint
Commandlet/PrepareAssetsForCookingCommandlet.cpp 7 material instances

Loading a Blueprint there drags the Kismet compilation manager into PreInit,
which lazily loads the LiveCoding module, whose StartupModule then creates a
CDO and dies in CastChecked<UPackage>. -NoLiveCoding does not help: it
disables the feature, not the module load.

LoadAssetMaterialsCommandlet additionally dereferences the finder result with
no null check (RoadPainterBlueprint.Object->GeneratedClass), so a genuinely
missing asset is an access violation rather than a log line.

Suggested fix

Do not load /Game/ assets from CDO constructors in a PostConfigInit module.
Resolve them on first use with LoadObject/LoadClass instead. For
ATrafficLightManager that means moving the 14 finders into a
LoadDefaultModels() called from GenerateSignalsAndTrafficLights(), which
already null-checks the models it needs. Plugin-mounted paths (/Carla/...,
as in OpenDriveActor.cpp) are fine — they mount with the module.

This is not hypothetical for other projects only: it is why the plugin cannot
currently be dropped into an existing Unreal project.

Environment

  • CARLA ue58-dev-carla @ de3f38e64, CARLA fork of UE 5.8, Windows 11

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions