Search code examples
iosxcodedebuggingxcode4grand-central-dispatch

Debugging with semaphores in Xcode - Grand Central Dispatch - iOS


Say have a few blocks of code in my project with this pattern:

 dispatch_semaphore_wait(mySemaphore);
 // Arbitrary code here that I could get stuck on and not signal    
 dispatch_semaphore_signal(mySemaphore);

And let's say I pause in my debugger to find that I'm stuck on:

 dispatch_semaphore_wait(mySemaphore);

How can I easily see where the semaphore was last consumed? As in, where can I see dispatch_semaphore_wait(mySemaphore); was called and got through to the next line of code? The trivial way would be to use NSLog's, but is there a fancier/faster way to do this in the debugger with Xcode 4?


Solution

  • You can print debugDescription of the semaphore object in the debugger (e.g. via po), which will give you the current and original value (i.e. value at creation) of the semaphore.

    As long as current value < 0, dispatch_semaphore_wait will wait for somebody else to dispatch_semaphore_signal to increment the value.

    There is currently no automatic built-in way to trace calls to dispatch_semaphore_signal/dispatch_semaphore_wait over time, but that is a useful feature request to file at bugreport.apple.com

    One way to trace this yourself would be by creating symbolic breakpoints on those functions in Xcode, adding a 'Debugger Command' breakpoint action that executes bt and setting the flag to "Automatically continue after evaluating" the breakpoint.

    Another option would be to use DTrace pid probes to trace those functions with an action that calls ustack().