Monobehavior infinite loop detection

Hi,

is there a way in Unity how to find last event function(Start,Update,…) that was called by engine execution? Would be nice to have this feature for debugging, to be able to find start of infinite loops etc.

PS: looking for some general solution, that is not modifying all the monobehaviors in the game.

Thanks

No, there is not. When unity hands over the execution to your code it’s only your code that is running on the main thread, If you’re blocking the main thread the game can not continue. Other threads run independent from the main thread, however the main thread is where your actual main loop runs.

There were (paid) solutions in the past like the Panic button. However this solution actually injected code into every single branch of your user code to check for an interruption request and raise an exception in place to terminate the execution at this point. As you can read on the assetstore site this seems to be no longer compatible with Unity 2018+.

This issue is generally known as the halting problem and it’s proven that it can’t be solved analytically. The main issue is how to actually stop / interrupt the main thread. This isn’t possible from the outside (besides terminating the program). So there has to be code inside the loop that allows it to terminate. The panic button I’ve mentioned above is extremely complicated / complex. Some people think Unity should have something built-in but injecting such watchdog code in every branch can severely harm performance.

So again, no, there’s no

general solution, that is not
modifying all the monobehaviors in the
game.

Avoiding writing infinite loops is a programmer skill that need to be learned and is just part being a programmer. It can happen from time to time. Though it’s generally just a sign that you probably rushed a bit too fast without understanding what you’re done or you made something too complicated that it’s hard to follow. Both a bad programming habits ^^.

edit

If you really have trouble to pinpoint where your code goes wrong, you can log to an external file from the threaded log callback. So even the main thread will lock up you would get the logs in your own file.

System.IO.StreamWriter m_Writer;
void OnEnable()
{
    m_Writer = System.IO.File.AppendText("YourLogFileName.txt");
    Log("Start Logging");
    Application.logMessageReceivedThreaded += HandleLog;
}

void OnDisable()
{
    m_Writer.Close();
    Application.logMessageReceivedThreaded -= HandleLog;
}
void Log(string aText)
{
    m_Writer.WriteLine(aText);
    m_Writer.Flush();
}
void HandleLog(string logString, string stackTrace, LogType type)
{
    Log("" + type + " " + logString + "

" + stackTrace);
}

Make sure “YourLogFileName.txt” contains a valid filename / path that can be written to. AppendText will create the file if it doesn’t exist yet. Otherwise it will append to the existing one. When done debugging you should remove / disable this script and delete the log file.

Make sure you actually use meaningful log messages. Don’t use countless “Here” or “Done” logs. Make sure when you see a log you know where it came from. Currently i include the stacktrace in the log. This could lead to hard-to-read log files. You may want to exclude the stacktrace in some situations. However the stacktrace helps to pinpoint from where this log was executed.

Debugging is a fundamental part of programming. You should do your best to avoid any logical errors. However at a certain size of project you can never be 100% sure that your code is “bug free”. So sooner or later you have to start debugging.

You can also use the VisualStudio debugger (attach to Unity) and set break points and step through your code to figure out what parts of your code run fine and where you get stuck.

Causing infinite loops isn’t so easy actually, it’s usually a bad while loop that never exits or bad recursion.
Might check for that, it shouldn’t be hard to pinpoint where it’s happening.