Debugging c++ with unreal engine 5.7

I do not understand why.
I tried to attach, build with the debugger attached and nothing.
The only thing I succeed was to break on a line while the editor was loading.
I tried delete intermediaire/saved/binaries and rebuild from ground. I disabled live coding.
I’ve selected DebugGame Editor / Win64 / MyGame + F5
I have log that confirm that the code is executed.
It’s been a week I’m on it and I think I’ll just give up unreal.
Anyone have this issue ?
I tried 5.7 and 5.7.1 (from launcher and github) with same result. Is this a known issue on these versions ?

I’ve already reinstall everything from the ground following step by step the documentation.

if linebreaks are triggering the interrupt and stopping execution flow, then the debugger is attached.
if you are using Visual Studio then you should also be seeing the output log, with a tab option for the callstack, and a separate box for the current scoped memory at the current execution step during the interrupted flow.

“DebugGame Editor” has nothing to do with attaching the debugger, and you can attach the Visual Studio or the Rad Debugger to any build level, some of them might not play as nice when the linebreaks happen, and for “cooked” games you will probably want the Rad Debugger more then the Visual Studio one, because part of Cooking is extracting the symbols.

the difference between “DebugGame Editor” and “Development Editor” has to do with flags, and how assert() and check() behave. for example in “Development Editor” the default is “warnings as errors = true” particularly with regards to the build tool.

opening your project through the [gameName].uproject will always be in “Development Editor”

in most cases a UE_LOG() print string is a lot easier to work with especially if you can inject other messages into the log, or using the DebugDraw functions for collision, geometry, and orientations. Attaching the debugger can be a hassle with needing to break on the right line, and with how long the engines callstack can get stepping through can be a chore with how many files need to be hot loaded. All on top of the overhead of the Debugger itself


maybe if you can explain the “unintended behavior” we might be able to help with either visual, or log based debugging instead of attaching the debugger itself.
does it crash?
does it use “random”/unexpected values?
does it “randomly” do something unexpected?

if you are going to provide code then the raw text in a “Preformated Text” block is easier then staring at a picture of text.

I’m in a fresh project. I just want to establish my developpment environment. Therefore I just start a template and put a breakpoint on a Begin with a log to be sure the code is executed. However you say that it’s best to work with log and not debugger or easier ?

The break point that is trigger when the editor is launching :

is on the class declaration (I don’t really know how its called) and it’s unintended because the game is not running and when I run the game, no breakpoint is reached but log is displayed. But the game run smoothly without any unexpected behavior.

For the code it’s just the Top down template with some log

when launching the editor for a given project:

  • the base types of the engine are processes, and the JIT compiler for Blueprints is loaded into memory
  • any EditorModules are indexed and associated for string resolution on reflection.
  • then the starting level is read from disk, and the first round of Actors in the level are processed (when you switch levels this same process is applied as well because a Level being loaded is a requirement of the Editor)
    • the dependent types and headers for the Actor are loaded into memory, include Component chains
    • the relevant constructor chain for the Actor will be run (this is where the default values for the actor are applied in the order of C+±>Blueprints->PlacedEntity values)
    • then the PreInitializeComponents() (ensuring that headers are loaded, requesting space, and starting instantiation), InitializeComponents() (ensuring all Components are instantiated and applying their default values), and PostInitializeComponents() (for cleanup and validating that everything is there; it is generally safe to check for and modify components of the current actor no earlier then PostInitializeComponents())
    • then the OnConstruction() and Construction Script are called.
  • this is repeated for each batch of Actors (for what is included in each batch, should be considered basically random which is one of the reasons you do not attempt to acquire specific Actors or Components of other Actors until BeginPlay() )

when you actually activate PIE:

  • a duplicate of the current Level is loaded (this prevents potentially doing write operations to the placed entities which could change a default value, and or corrupt the asset.
  • a World Object is only created at this time (there is technically a World Object outside of PIE, but attempting to access it will cause an ACCESS_VIOLATION (so the Get returns nullptr)
  • the same process is followed for each Actor in the level
  • once all actors are loaded and all OnConstruction() and ConstructionScript() have not reported any errors
  • Then and only then does BeginePlay() run

for standalone Play, or Cooked application follows the process of PIE but instead of copying what is currently in the Level it is done from disk.


the reason that in the vast majority of instances you will not be launching the editor with the Debugger attached has to do with:

  • how heavy the Engine already is
  • the debugger makes the editor take longer to load
    • in some cases the actual instructions being loaded are different (some things that have ASM optimizations are elevated to structured English resulting in “similar” but slower performance)
    • the expanded symbols for the byte code that is generated on your C++ is retained in memory leading to a higher footprint
  • because the program has been informed it could receive and Int3 (interrupt3) some tasks are switched from asynchronous to synchronous to prevent runaways

if you put a breakpoint in a rather common code path in the hopes of finding the one time an outlier event happens; if the outlier does happen you will be doing a bunch of continues in the hopes to see the reason for the outlier in the CallStack, or the memory snapshot (assuming that the segment of memory wasn’t “optimized” or scoped away). Then to utilize the CallStack or memory snapshot you would need to have a very good understanding of what “acceptable” values are.

because of all of these the debugger is most often a Last resort “If I have toooooo” tool.

where using Log based on Visual debugging is far easier. With LiveCoding you might not even need to relaunch the editor presuming you remember to put the * on your strings into the UE_LOG macro

  • with LiveCoding the only big issue is to never modify a header file, or you are very likely to break values, if a header needs to be modified particularly adding and removing members or types then close the editor and relauch.
  • changing a members default value in the header declaration is likely to never happen, but “shouldn’t” corrupt the values.