How to track all Update() calls to find infinite loop

I’m trying to track down a suspected infinite loop within our game. We have a massive project containing many loops - some written by us, some written by a previous company, and some contained within third-party plugins. At random times when running the game, the player will stop rendering, the Windows blue spinning pointer will appear, and clicking the window will cause a Windows “Not Responding” dialog to pop-up.

We’ve tried attaching the process to both the MonoDevelop debugger as well as Visual Studio, but both give no information when crashing, which is leading us to assume an infinite loop is the problem. We tried pausing the debugger after it froze, but that actually sends Mono into a frozen “Not Responding” state and never comes out.

But one idea we had was to print (to a socket) an “I’m here…” statement from the Update() call of each GameObject, so that we could hopefully narrow down the last Update to be called before entering the frozen state. The only problem is that we have 1380 instances of GameObjects stemming from 214 MonoBehaviour classes, some of which are empty base classes used for multiple derived classes which then contain the Update() implementation. So I was wondering if there were any ideas out there for triggering a print statement any time a MonoBehaviour.Update() call was made while knowing the caller? Or maybe wrapping MonoBehaviour into a “CustomMonoBehaviour” which could extend the Update() function somehow? Any suggestions would be greatly appreciated!

(Building for Windows 7 using Unity 4.5.0f6)

Edit: Added details on Mono crashing when trying to pause after the player freezes up.

A better solution for your problem would be to run the game from MonoDevelop/Visual Studio in debug mode so you can set breakpoints. They are much more dynamic and fit better for finding little bugs and tweaking things to it’s optimum when compared to unity’s Debug.Log();

Cheers

From you description, it cannot be determined whether the game halts or unity crashes? (is that the player or editor?)

Adding some print code to all Update methods is possible using a framework such as Mono.Cecil (Unity also uses this framework for various tasks).

Cecil lets you read assemblies and mess with them at the IL level, so a possible solution would be to read all assemblies that are executed in your project, and for all MonoBehaviour classes that implement an Update method, inject the IL code needed to call some custom reporting method that would log some information.

Personally, i would do this only as a last resort, since it involves coding, learning how to use Cecil, testing, etc.

I would attempt to use a native debugger (WinDbg) if on Windows. It can attach to a process and will (perhaps) allow you to get a clear stack trace when Unity crashes.

This will be a native stack trace though, but it may show what object/component the native code was calling when it crashes.

So, to sum it all up:

  1. Try to use a native debugger on either the editor or a standalone windows player.
  2. If that failed to produce any helpful information, attempt to implement a solution using Mono.Cecil that will inject IL code to your assemblies.

I would be happy to elaborate on both of these options, if needed.