Memories… programmer friendly assertions in Xcode

Well, things certainly tend to come around. After almost exactly 6 years, I once again find myself wanting to programmatically pause a program at interesting times for inspection using gdb. Where the code decides what’s interesting, mind you, not the developer’s symbolic breakpoint. Those six years have brought a new platform (iOS) and three new CPU architectures, so that trusty macro referenced in the link needs some updating. And update it I did – see the code fragment below.

O, and by the way, that’s gdb in its friendly Xcode disguise, of course. There’s a limit to how much mental abuse I can take, and that limit is comfortably reached by having to manually manage memory in Objective-C. I feel your pain, my embedded hardware brethren.

What I want…

So, we need to insert some code to break at a certain point or condition. A staple assert (false) won’t do, because there’s only so much you can do after the assert fires the near-fatal SIGABRT signal. You won’t be able to continue the program, or rewind the program counter. You probably won’t be able to use all that symbolic debug information in a very meaningful way. Admittedly, you can probably set up signal handlers in the debugger to pause on SIGABRT, but being a developer, you will forget that at least on the one occasion when it really mattered. And sometimes the interesting time is just interesting, not the beginning of the end of your program.

But there are other signals! SIGINT is a fine candidate to bring up the debugger. It will catch the signal and generally save your life. But there’s a snag. And another snag. The first is that SIGINT will kill your program when not run under the debugger. Unless you set up a signal handler or sigmask, but you’ll only do that in at most one or two of your applications. This is bad, because I’ll often just Run, not Debug,  development builds trusting Xcode to debug “just in time”. And this works fine for, e.g., segmentation violations. So why shouldn’t I have that for my programmatic breakpoints?

The second snag when using a plain kill is that the debugger will stop in the wrong stack frame. I have chosen the bold type to prevent the use of expletives. This frame mismatch requires me (and you, should you choose this ill-advised way) to navigate all of the two stack frames up to the point where your actual call (and probably the failed condition) is. Only two clicks of the “step out” button for the casual observer, but a huge productivity and mood sink for the developer who’s been observing the app not so casually for half an hour waiting for the bug to occur. This does not happen with gdb breakpoints. This does not happen with segmentation violations. So why should I have to put up with it for my programmatic breakpoints?

Read the rest of this entry »