Debugging NullReferenceExceptions in iOS Games

I'm currently getting crashes ("it simply disappears") in my game when running on the device. The message I get from the Xcode log is:

Unhandled Exception: System.NullReferenceException:

Debugger stopped. Program exited with status value:1.

The issue is 100% reproduceable on device (i.e. it happens every time) - but it never happens in the editor. While I do have some conditional compilation it's very unlikely that any of that makes the difference for this issue.

So, I've been trying to nail this down for a little while and finally decided to give the new on-device-debugging feature a try. This is working really great when I'm setting breakpoints. And fortunately MonoDevelop also provides the possibility to break on exceptions - so I also tried adding a break-condition for "System.NullReferenceException". But that never is triggered (but the issue is 100% reproduceable).

So, I created a test case to see if "break on exception" is really working in MonoDevelop, and it is: I built a deliberate NullReferenceException into the game when clicking a button, and when I add System.NullReferenceException to the exception triggers, MonoDevelop nicely stops when the exception occurs. So, for these cases it really does work (nice ;-) ).

Unfortunately, it doesn't help with my crash because there it still doesn't trigger.

So, there's three interesting things / questions:

a) This is the log in Xcode (when executing in Xcode; not when debugging, of course ;-) ):

Program received signal: EXC_BAD_ACCESS. warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).

So that's different from the exception I'm trying to hunt down. Also - on this exception, my game simply freezes, while on the exception I'm trying to hunt down it "disappears". And, of course, I'm seeing this one in the editor as expected.

Why am I getting a System.NullReferenceException in the Xcode log one time, and a EXC_BAD_ACCESS the other time? Why do I get a "freeze" one time, and a "disappears" the other time?

b) My deliberate NullReferenceException does trigger the break-condition when debugging with MonoDevelop. So, in theory there would be a really easy way to find NullReferenceExceptions on the device - only it doesn't work for the specific case I need it for.

What could cause this?

c) When I play the game started from Xcode or started from the device without the debugger attached, the "crash" makes the game disappear. When the debugger is attached, the game just freezes - but the debugger doesn't go anywhere.

NOTE: While testing, I realized that sometimes MonoDevelop doesn't really seem to attach. Well, actually it does (it also leaves debug mode when the app is terminated on the device) - it just doesn't stop with the breakpoints. So, I thought maybe that's why I never got my exception triggering a debug-stop. But either breakpoints work or they don't - and I made sure to test in a session where they did work.

Ah, it's good to have Unity Android as well: Turned out I was wrong with the "it's likely that it's something specific to the iPhone", in fact it was. So now that I know what the exact issue was, I also have an understanding of what the difference between my test case and the actual problem was:

Seems like the difference with NullReferenceExceptions is whether it happens on game objects or just plain C# objects. My testcase was with a string - the actual problem happened on a game object that was either destroyed or deactivated (still need to do some further testing on this).

So, when it's "really null", you get the EXC_BAD_ACCESS thing. When it's one of Unity's "special states" with its game objects, you might get the System.NullReferenceException. The first one seems to be comparatively easy to debug using MonoDevelop remote debugging, the latter one probably only works with trial and error or, if you have Unity Android, by trying it there and hopefully, you'll get the same issue there.

So: I saw the NullReferenceExceptions in my Android build - so I was lucky on that one. I probably would have never found this particular issue any other way (or it would have cost me many, many more frustrating hours).

check this tool