Download

Is it normal that the editor crashes when I have a bug in my code?

I mean, come on… I try to access some null pointers and the editor crashes?
Is there any way to avoid this (besides testing nulls everywhere)?
Can’t just the editor catch this errors (I know it is catching them because the “send error report” shows up with the stack trace) and deal with the error, like showing a popup with the error instead of plain crashing?

anything null will crash the editor, and yes you do have to check for it

you can try


if(object == nullptr) // set objects to nullptr in the header file or they probably get random values and this doesn't work

if(object)

if(ensure(object))

if(object.IsValidLowLevel())

if(object.IsValidLowlevelFast())

Maybe someone can say what the best method is, I would also like to know the best way

I figured that testing nulls would avoid the crashes, but couldn’t Epic avoid the crashes and show a user friendly message?

We live in hope…

I guess it adds a layer of complexity that ultimately hurts performance. I got used to checking everything checks out before I use it / or construct it, as its a few words that saves a lot of headaches later on.

This crashes on asserts… I’m really getting tired of restarting the editor.

It depends on the type of pointer.

  • UPROPERTY raw pointers

    • if(SomePointer != nullptr) or simply if(SomePointer) will suffice. These pointers get set to null automatically when invalid.
  • Unreals Smart pointers (TUniquePtr TSharedPtr, TWeakPtr)

    • Use IsValid()

So make it a good habit of marking all your raw pointers as UPROPERTY so the garbage collector can do its job.

Never use IsValidLowLevel or IsValidLowLevelFast unless if you know what you are doing.

It is not necessary to set UPROPERTY raw pointers explicitly to nullptr since it is already taken care of.

ensure is a type of assertion that can be used during development. If the game crashes then any ensure conditions that returned false will be shown in the log.
Shipped games expects these to always be valid.

Assertions is very useful during development so instead of silencing behavior that you expected to be executed you will be notified about it when it happens.
If you attach the Visual Studio Debugger it will catch (stop execution) when an ensure condition fails giving you a chance to correct it.

I think that you’re misunderstanding how C++ errors and how the crash reporter work. The crash reporter can be setup to run when an exception (the null pointer access) occurs but there is absolutely no way for the engine to continue from that execution point, it’s out of the engine’s hands. It’s the CPU that has failed because you told it to do something it can’t do. The best Epic can do is provide the callstack for you so that you can identify the crash and fix it.

You really only have 2 choices: 1) allow code like this to crash and write code in such a way that should guarantee it never happens or that it’s supposed to be fatal or 2) null check your pointers everywhere (unless you have some other reason to believe that they’re valid). If you haven’t heard of “defensive programming” that a new research topic for you.

In the case that Epic can control, Blueprints, they do allow for graphs to continue executing but only because they’re doing all the null checks for you and skipping the calls that are illegal before they get to the CPU.

1 Like

I think I’m well aware of that.

But UE Editor could work just like Visual Studio does. A bug on a program doesn’t crash Visual Studio because the program runs in a separate process.

I don’t have enough knowledge of UE to know how the architecture is setup, but based on the behaviour I’m experiencing it seems that the game is running under the editor process, so a null pointer reference or access violation will crash the editor, and yes, in this case, there’s nothing to be done.

New for me maybe 20 years ago. :wink:
But defensive programming is not about putting if ! null everywhere.

The “Standalone Game” play mode runs it in it’s own process. The downside is that you can’t debug through the editor anymore (eject, world outliner, changing properties, viewing blueprints as they run, etc.), which would explain why PIE runs in the same process as the editor.

Game Flow Overview | Unreal Engine Documentation. I found this interesting. This tells you the process of starting the engine and launching a game for both the editor path and standalone path.

1 Like

This is because of how C++ development work, or how Unreal Engine “play in editor” works by building/loading a DLL straight into the editor process. The reason C++ can go faster than most other environments when it works is that it doesn’t have any of those features for testing things that more managed languages may have.

This is what it means to develop in C++. You either learn to do it, or use some engine/system that uses a slower but more convenient language. Those are your options.

For what it’s worth: Blueprint is one of those “slower but more convenient” languages. If you stick to Blueprints, then any “None” reference will not crash the editor. You may want to stay Blueprint-only if that’s the experience you’re looking for.

Or you can “run in separate process” when you test your game. You may want to script some hotkey in Visual Studio to attach to this separate process (probably by name) to be able to debug it that way, though.

1 Like

I mean, some times it does :wink: . Seriously though it sort of apples and oranges. Visual Studio is an IDE, but the Editor is the game. This is one of the downsides of an integrated editor.

That’s true, but if you’re defensive in the places that matter your game process won’t take down your editor.

A bug on a program doesn’t crash Visual Studio because the program runs in a separate process.

You can do this in unreal engine editor, use Play on Standalone Game instead Play in Editor.

The code you write also runs in the editor, not just in the game.

It can be – if you go willy nilly dereferencing null, you’re going to crash.

It is generally better to make clear invariants in your code for where values can and cannot be null, and where/when. Code will become easier to read and reason about when you establish and enforce these rules. And, at that point, crashing on a NULL when you have a rule that “this cannot be null here,” is a GOOD THING, because it shows you directly where there is a bug, so you can remove the bug.

Unfortunately, C++ makes making and enforcing these rules super hard. Sometimes I wish we’d have something nice like Haskell or Rust to manage these kinds of rules – or just something like user-defined cv-qualifiers – to manage these kinds of complexities. The storage-and-templates model of the C++ type system just isn’t strong enough to help out here, so it has to be done with comments and ASSERTs.

This.