Archive for category Debugging

NSTimer Out of Sync with Device Clock?

I encountered this puzzle recently:  How does a 60-second, repeating, NSTimer drift way out of sync with the iPhone’s system clock?  The timer was created with a fireDate that was on the even minute with the clock.  It fires at 11:02:00 AM and 11:03:00 AM, etc.  But users report the timer firing at 1:23:30 PM for example.

(And we are not talking about timers not firing because the run loop mode changed temporarily.)

It turns out that the clue is the word “iPhone”. The NSTimer does not drift from the system clock, the system clock drifts from the NSTimer.  The iPhone can have its clock adjusted during the day by the cellular service, especially if the phone goes out of service and comes back. (Changing locations to a different time zone probably triggers it too.)

You can make it happen by just setting the device clock manually.  When you pic a new time, it jumps to the hour and minute chosen, but with zero seconds.  The iOS honors the repeat rate from the last firing and adjusts the fireDate accordingly.

So if you need to stay tuned to the clock, you’ll need to update the fireDate on the NSTimer when you receive the significant time update notification.

Tags:

Fix to Symbolicate System Symbols in iOS 5.0.1 (9A405) Crash Logs

I found this one many weeks back and had it in my to-do list for the blog.  Now that 5.1 is out, I feel guilty I didn’t write it up sooner.  But then, my day job is keeping me very busy.

I had a long period where I could not fully symbolicate crash logs that were made by iOS 5.0.1 devices.  The symbols of my app would be symbolicated, but the system symbols of the device would not.  I was especially frustrated because a coworker with the exact same version of XCode could symbolicate those system symbols with no problem.  Neither of us knew why.

After a huge amount of searching with Google and reading items on StackOverflow.com,  I finally found a note saying the symbols in the iPhone 4S were corrupted somehow and they should be replaced with symbols from another device.  I don’t know if there was a problem with all the iPhone 4S devices, or just some of them or just early ones.

As much as I tried to do this,  I still could not symbolicate properly.  I triple-searched my computer for all copies of symbols for 5.0.1 (9A405) and removed them.  (You can compress them into .zip files if you want to keep them just in case.)

What I needed to know was to look in ~/Library/Developer/Xcode/iOS DeviceSupport   Xcode 4.2 had been putting device symbol information in there.  Once I got rid of that folder, and attached a device, XCode pulled a new copy of the symbols and symbolication worked like a charm.

Top top it all off,  something about the symbolication script in XCode 4.2 works better than any of the previous symbolication scripts, either from Apple or from any developer site.  While symbolication inside XCode can be horribly slow, it does work pretty well.

Hope that helps

Tags: , ,

Solid Code: Mixing Objective-C and C++

If you’ve noticed that there’s been a long time between this post and the previous one,  you are right. My day job has been keeping me busy.  But that’s why I can get on with the topic: mixing legacy C++ with Objective-C.

After trying things a few ways,  I’m finding that one basic assumption difference between the languages can trip you up: the assumption about calling a method or function with an object pointer to zero (a.k.a. nil or null or NULL).

Since the C++ will generally be legacy code,  its natural for Objective-C objects to wind up containing pointers to C++ objects.  After that, its pretty easy to wind up calling C++ functions almost directly from accessors like:

This is functional,  but from a solid-coding standpoint,  it is too bug-prone and too hard to debug.  If the above statement crashes, which part of it failed?

Objective-C assumes that calling member methods with nil object pointers is OK.    (i.e., a nil ‘self’ pointer is not an error.)  Any such attempt just automatically returns zero.

C++ however, assumes that member functions will never be called against a NULL pointer.  (i.e., a NULL ‘this’ pointer.)  Any such attempt will probably crash an iPhone with EXC_BAD_ACCESS.

My point here is you should put the pointer into a variable, then call the function from that variable:

Now the language assumptions are clearly separated.  Nil pointers in the first line can be safely assumed to have zero method results. And the C++ in the second line can be more easily debugged if it fails.  (And we can easily check our C++ pointer for NULL before calling its function.)

The crash from the C++ code will most likely happen when the member function tries to dereference a member variable.  An instance’s member variable is held at an offset from the pointer, so if the pointer is zero, the member equates to an address that is near zero.  Addresses near zero are invalid on the iOS.

So there you go,  if you have to mix Objective-C and C++,  avoid mixing them on the same line.

Tags: , , , ,

XCode 4 – Stopping in the Debugger on NSAssert

I’m not sure if XCode 4 makes this technique unnecessary. Since I originally wrote this, I’ve seen XCode 4.0.2 stop at NSAssert on its own, without me setting this breakpoint. But it may be helpful to someone somehow. So here it is:

Xcode 3: Run Menu -> “Manage Breakpoints”
XCode 4: Go to the breakpoint navigator.

Click the + button at the bottom of the navigator, select “Add Symbolic Breakpoint…” from the contextual menu that appears.

In the “Symbol” box, enter

Then click “Done”. (NOTE: this is the default assertion handler. If you are using a custom assertion handler, you probably need to specify a symbol for its object and method.)


Now execution will break immediately on assertion failure. And very usefully, XCode shows the nearest source code of the stack, not the assembly of the assertion handler.

Tags: ,