Circular Dependency causes UHT crash

I was coding away today when suddenly Unreal Header Tool started crashing on compile. After some tinkering, I threw UHT into the debugger and traced the call stack to a section in FHeaderParser::ParseHeaders that checks for circular dependencies, which made me realize I accidentally introduced a circular dependency.

Once the circular dependency was fixed, UHT stopped crashing.

Hi pdylanross,

Would you be able to provide some additional information about this issue?

  • Was the circular dependency in the code in your project, or were you editing the Engine source code?
  • Do you recall how you had created the circular dependency?
  • What version of the Engine were you using?

It was in my project, not engine source. I can’t remember how I created it exactly, but I think I had two uclasses that included each other’s headers. They might have had stored refs to instances of each other too. It was probably on 4.7.3, but not sure. One of the source-built 4.7 versions, I just keep my engine up to date with the release branch.

I tried to reproduce this using 4.7.3 built from source code. When I added two new Actor classes to a project and added an include for the other actor into each one, creating a circular dependency, it provided a compile error, but no crash. I also tried performing a hot reload, but that gave the same compile error. It seems like there may have been something very specific about how your circular dependency had been set up that caused the crash.

I will keep poking at this to try to recreate it, but if you can think of anything else that you may have done to create the circular dependency, that would be very helpful.

I poked around in that section of my code to remember what I had done, and I think this is it. I had an enum for character types, a character base class, and a struct that I use in my game instance to describe which pawn gets assigned to which character type. This allows me to easily reference which pawn gets assigned to which character type in the class defaults in my BP game instance. I declared the struct in the same file that I put the enum in, and I included the base class for characters, which included the file that the enum & struct were included in. I fixed it by moving everything to their own files and using some forward declaration.

I played around a bit with the information that you provided and this is what I ended up with:

  • A UObject class containing a single UENUM and a single USTRUCT, and nothing else. It includes the base Character class.
  • A base Character class. It includes the UObject class.
  • A GameInstance class. It includes both the UObject class and the base Character class.
  • The USTRUCT contains a pointer to a base character class actor, as well as an instance of the UENUM.
  • The base Character class contains a TArray of the USTRUCT.
  • The game instance class references the USTRUCT TArray in the base Character class.

Does that sound similar to what you had? Should I move the array to the GameInstance class and reference it from the base Character class.

Not quite. It went like this:

  • A file with a UENUM (character type) and a USTRUCT ( enum instance and TSubclassOf Base character AActor) that included the base character class header
  • A file with the base AActor character class that included the file with the UENUM
  • A File with the GameInstance that had a TArray of the USTRUCT to be filled in that included the file with the Enum & struct as well as the file with the base character AActor

Also I did some digging on my hard drive and found that I still have the call stack from UHT when it crashed. I thought that it had gotten killed in a recent HDD crash, but luckily that’s not the case. Here. Sadly, it doesn’t tell much other than it got stuck in some sort of infinite recursion.

Thank you for the additional clarification. I tried using the setup that you just described (in 4.7.3 again), as well as a few variations on that setup, but I am still getting the circular dependency compile error instead of a crash. Just to confirm, this isn’t an issue that you are still experiencing, correct? I’ll keep playing with this from time to time, but if it is not blocking you from working on your project I will mark this issue as resolved for now.

Oh yeah, as I stated in the OP, it was fixed when I fixed the circular dependency. It’s not an error I make very often so I haven’t run into it again, but if I do and it crashes I’ll give you a more detailed report of what happened. Sorry it took me a minute to remember how I had it set up exactly, but this was almost a month ago and I had a pretty heavy workload at the time so things are a bit hazy.