iOS Crash Reports from Unity3D Games

We noticed customers complaining about crashes at launch of our Unity iOS game Hit Tennis 3. This was a problem we could not reproduce, and it lead us down a rabbit hole dealing with both ObjC and C# crashes. Read on to find out how to use iOS crash reports with Unity games, and how to get crash logs from your C#/Unityscript code too. For years now iOS and iTunes Connect have conspired to collect crash reports from real users, gather them up, let us download them from iTunes Connect, and view them in Xcode. However, this system has been very broken in Unity games. Maybe Unity didn’t think it mattered because Unity games aren’t written in ObjC, so who cares about iOS crash reports? Well we care. Our games have lots of native iOS code we’ve written, and we use a bunch of third party iOS libraries too. You know, for useful stuff like UI, analytics, configuration management, advertising. And anyway, for free Apple will gather crash logs and tell us which kinds of crashes are the most common among real customers. Who doesn't want to know that? So here is how to fix it and get your Unity iOS crash reports back…

Crash Symbolication and Dsym Files Explained

When an app crashes, iOS makes a crash log that shows the execution stack of the crashed thread so you can see what code was running when it crashed. A running program’s execution stack is a bunch of memory offset address of code for each method call along with parameter data. Programmers don’t know their code by memory addresses; we know it by source code line numbers. When the code is compiled, there are Xcode settings to include debug symbols into the app. These debug symbols enable iOS to generate a useful crash report with line numbers of the source code, instead of just a bunch of impossible to understand memory addresses. At least that’s what happens for debug builds. Stuffing the debug symbols into the build makes it bigger than it needs to be, so debug symbols get stripped from app store builds.  That means that crash logs from real users don’t have source code line numbers, they only have memory addresses, which makes them incomprehensible. Apple planned ahead for all this though. Xcode can compile with the ‘DWARF with dsym file’ setting. The dsym file is a lookup table that converts from the memory offsets to source code line numbers. Xcode stores the dysm file in the build archive, and it will automatically find the correct dysm and ‘symbolicate’ crash reports so that it shows method names and source code line numbers:

symbolication1

 

 

 

 

 

 

 

To do this you download a crash report from iTunes Connect, and then you drag and drop it into the ‘device logs’ area of the Organizer’s devices tab. It’s brilliant when it works, but it relies on your Xcode project build settings be just right.  When Unity generates the Xcode project it uses different settings that result in no useful dysm file (either no dysm file at all or a dsym file with no symbols). This means crash reports can not be symbolicated, making them useless. (As far as I can tell this is for no good reason, I think its just Unity’s mistake.) However it’s your Xcode project not Unity’s, just fix the settings right and you’ll have good builds.

symbolication2

Correct Xcode Settings for Dsym Files

Here are the Build Settings you need, courtesy of capyvara on Unity Answers. (This isn’t something you can do after the fact. To make this work you will need to submit a new build to the app store and wait for crash reports from that new build.)

  • Build Options -> Debug Information Format: "DWARF with dSYM file"
  • Deployment -> Deployment Postprocessing: Yes (hmmm, I have 'No', but it works...?)
  • Deployment -> Strip Symbols During Copy: Yes,
  • Deployment -> Strip Linked Product: Yes
  • Deployment -> Use Separate Strip: Yes (again, I actually have no).
  • Linking -> Other Linker Flags:   remove these: "-Wl,-S,-x"
  • Apple LLVM compiler - Code Generation ->  Generate Debug Symbols: Yes

symbolcation3

 

iOS Crash Reports for C# or Unityscript crashes.

For an app store build, Unity recommends using the player setting ‘Script Call Optimization: Fast but no exceptions’. With ‘fast but no exceptions’ the normal C# error handling is removed from the compiled code for performance reasons. With ‘fast but no exceptions’ if you try to dereference a null object reference in C#, instead of getting a null reference exception the game will just crash. While some would argue that you could run in ‘Slow and safe mode’ for an app store build and hence get null reference exceptions rather than crashes, that won’t really help most cases. Throwing exceptions in the middle of game logic will mean that Update loops or other parts of your game code won't be running all the way though. That just results in a broken game that limps along. Better to get crash reports you can find out about and fix. But Unity 4.1 and earlier, when the C# code crashes, Unity would shut down the app cleanly without generating a crash report. So iOS would not know there was a crash, and no crashes would be reported via iTunes Connect. This is a big problem if you are paying attention to crash reports in iTunes Connect -  what if the vast majority of game crashes are in your C# / unityscript code? By looking at iTunes Connect you would never know. You’d only know when users complaining in emails and app reviews. The problems we were dealing with were crashes during startup, so it was even harder for users to even email us… they can’t tap the ‘Contact Us’ button in the app if the app never even starts up! The good news is that Unity 4.2 fixes this, and by default if the C# code crashes then Unity will actually crash the whole app. iOS will see it and report to iTunes Connect.

So this is easy: update to Unity 4.2, and submit an update to the App Store. Note that these are still iOS crash reports, so you will see a C stack, not a C# stack. First off, its good to know you are getting crashes, iTunes Connect will tell you which kinds of crashes are most common. Second, your C# code is compiled to a native executable, so you will still see symbols you recognize from your C# or Unityscript.

Unity 4.2 has additional crash reporting features that you can choose to enable. Its possible to query from code for a previous crash the next time the game starts up, and crash logs can be sent to a third party server. However these are still iOS crash logs, not C#/unityscript crash logs. So I’m not sure what the point of that is… iOS and iTunes Connect do this anyway. I guess using a third party crash reporting service will collect more crash logs and collect them faster than Apple does, but the basic service from Apple has always be fine for us.

In Part 2 I’ll describe how we get logs from real players to figure out crashes in our C# or Unityscript code.

 

iPhone Development Books 1: Learning iOS Programming

bookshelf
bookshelf

I own 91 books covering iPhone app programming, design, marketing, and business, and I've browsed plenty more. From all those books I've picked out the ones I consider to be the very best. My recommendations are split into four parts:

Learning iOS Programming (below)

Design for iPhone and Mobile Apps

Building iPhone Games & Unity 3D

Marketing iPhone Apps & Business

'

Part 1 - Learning iOS Programming

Learning to program the iPhone & iPad has never been easier due to some fabulous books. Programmers who are new to Apple have to learn Apple's Cocoa Touch SDK and in most cases will be learning Objective-C as a new programming language too. Of the 21 iphone programming books I've read, here are the best...

I recommend you start with Beginning iPhone 3 Development – Exploring the iPhone SDK (soon to be updated to 'Beginning iPhone 4 Development'). Jeff LaMarche and Dave Mark clearly introduce and explain the most important topics to get new iOS developers over the initial steep learning curve. Of all the iPhone books this remains the best for developers new to iOS. They have a companion book 'More iPhone 3 Development', but you won't need that unless you later want to delve into advanced topics.

Another great book for learning iOS programming is iPhone Programming: The Big Nerd Ranch Guide by Joe Conway and Aaron Hillegass. This books is written by the premier iOS and Mac training company in the world. It covers more topics than Beginning iPhone 3 Development, but it still starts out slow and easy, has a lot of great explanations of 'good ways to do it' and it includes introductions to Apples iOS development tools too, so you get a very well rounded kick start on the platform. Because it covers so many topics it makes a good reference later for stuff you forget.

If you like books with lots of text to explain stuff, you should start with 'Beginning iPhone 3 Development' if you hate lots of text and really just prefer short lessons on 'how to do it on iOS' then start with the Big Nerd Ranch book. But people, this stuff is really difficult when you first start, so its worth having both so you can hear two different voices when you get stuck.

Once you start writing your first app you'll find there are lots of little specific things to figure out, your best bet is to check with Erica Sadun first by looking in the pages of her wonderful book 'The iPhone Developer's Cookbook'. Its a great companion for any iOS developer, and its the one book I refer back to most often.

Programming for iPhone means programming in Objective-C. Objective-C is the C language, with dynamic object oriented extensions. Coming from any other language, you'll need to learn the Objective-C way, and for that you should check out ‘Learn Objective-C on the Mac', though there are a bunch of newer Objective-C books I've not seen (if you find one you love, let me know). Also consider adding 'Programming in Objective-C' by Steve Kochan to your library, as this is the comprehensive language reference, it will have the answer when you are trying to figure out more complicated parts of the language. Some of the more advanced parts of iOS development, eg audio processing, are done in C rather than Objective-C. This means that when you get to those you'll need to understand the crazy C stuff of pointers to pointers to functions returning references to arrays of pointers to alloced memory buffers... If all those stars and ampersands get you down you should go back to an easy learning C book, of which there are many, eg ‘Learn C on the Mac'.

More book recommendations:  App DesignGames & UnityMarketing & Business.

Debugging Tip – objc_exception_throw breakpoint

If an exception is thrown when debugging an iPhone app, without your own exception handling code, that exception won't stop the debugger until the call stack has totally unwound. On that journey through the call stack it gets caught and disguarded in the event loop. That's a bummer because then the debugger can't show you where original exception was raised. This problem is easy to fix by adding a symbolic breakpoint for the runtime's objc_exception_throw function, which is called as soon as the exception occurs. Here's how: 1) Run the app in the debugger. There's an exception we can see in the debugger console:

screen 2

2) Open the debugger from XCode menu Run->Debugger. The stack we can see where the debugger paused is the useless stack where the event loop code caught the exception and then bombed out with its own exception.

screen 4

3) From XCode menu Run->Manage Breakpoints -> Add symbolic breakpoint we add 'objc_exception_throw'

screen 12

4) Now when we debug run again, the debugger stops as soon as the oringinal exception was thrown, we can see exactly where, and we can poke around an inspect variables etc.

screen 11

Memory Management Basics Tutorial Video

This article is a screen cast video of my tutorial for beginner iPhone programmers, it's about the basics of memory management in Objective-C. Memory management is a tough nut for the beginner to crack, particularly in Objective-C and Cocoa for iPhone. Check out my iPhone memory management reading list for more voices on memory management. The tutorial covers: Objective-C object retain counts; using retain, release, and autorelease; explains the autorelease pool in detail and how it works with the event loop; rule of thumb for if an object is in the autorelase pool.


Part 1: retain counts


Part 2: auto-release pool and the event loop


Part 3: auto-release pool and the event loop with retain


Part 4: auto-release pool wrap up


Part 5: properties, dealloc, bugs, auto-release rule of thumb

Thanks for watching!

iPhone Memory Management Reading List

It's a topic that can be explained several different ways, so keep reading and experimenting till it clicks for you.

... Books Learn Objective-C on the Mac Cocoa Programming for Mac Programming in Objective-C Online Practical Memory Management from Apple Memory Management Guide from Apple Dr Dobbs Mac Developer Tips Memo.tv mauvilasoftware.com Stepwise.com Tristan O'Tierney Mac Developer Network Video O'Reilly and here Cocoa Dev Central Cocoa Dev HyperJeff's list of resources WikiBooks Devplace Woojijuice Peter Dikant   

Read More

What Color is My Pixel? Image based color picker on iPhone

iPhone's cocoa touch doesn't seem to have a call to get pixel color from the screen or an image, which I needed to make a simple image based color picker. Here's a solution to do this using an offscreen graphics context we can use to get pixel by pixel data from the image. I've wrapped up the technique in a new class ColorPickerImageView and there's a complete demo XCode project you can download to see it in action.

Read More