Using code generated flags to debug with Instruments

I discovered a great debugging tool today from the article Flags: very useful when debugging with Instruments   The article talks about how to put up flags from your code that appear in the Instruments window.    This is a feature that is new to Instruments 4.0 and is described in the Apple docs at New Features in Instruments 4.0   Let’s jump to the end and show you an example of what you can put up in your Instruments display:

FlagDisplay

Note the yellow flags above the trace.   These were generated in my code within a loop.    If you click on a flag you can see the text that I generated for the flag “Loop index 38” along with the source file, line number of the code generating the flag and the method  being executed.

Setting up for flag generation

Adding a flag in code is as simple as adding the following import

#import <DTPerformanceSession/DTSignalFlag.h>

and calling one of the 3 predefined macros:


// Point flag (just an event in time)
DTSendSignalFlag("com.mycompany.mytracepoints.app.point", DT_POINT_SIGNAL, TRUE);

// Start flag (to mark the start of something)
DTSendSignalFlag("com.mycompany.mytracepoints.app.start", DT_START_SIGNAL, TRUE);

// End flag (to mark the end of something)
DTSendSignalFlag("com.mycompany.mytracepoints.app.end", DT_END_SIGNAL, TRUE);

Well … not quite that simple

The Apple docs mention in the section on Signal Flags that you do not need to link your application to this framework in order to use the macros.   In order to find the header DTSignalFlag.h you will need to add the framework to your list of libraries to link – at least temporarily:

DTPerformanceSession.framework

This will allow you to resolve the reference to DTSignalFlag.h

But don’t link the library!

I got the following warning when building after adding the framework:

ld: warning: ignoring file … file was built for unsupported file format …

After removing this framework from the list of libraries to link, the warning went away.   Interestingly, after I then deleted the reference to this framework as well, I was still able to build successfully (even after a Clean) and resolve DTSignalFlag.h.   Probably best to leave the framework headers in place though, since I’m guessing there was some compile magic at work here that would bite me later with the header gone.

Generating flags in code

Whenever you want to generate a flag, you can call the DTSendSignalFlag macro with the appropriate flag type (DT_POINT_SIGNAL, DT_START_SIGNAL, DT_END_SIGNAL).   I found that the first string argument could be any text you wish to use (verified this by looking through DTSignalFlag.h).

I wanted more flexibility, specifically the ability to use an NSString object where I could format the inclusion of variables, etc.  To do this I created the following macros:


// Point flag (just an event in time)
#define INSTRUMENT_POINT_SIGNAL(x)  {const char *cstr = [x UTF8String]; DTSendSignalFlag(cstr, DT_POINT_SIGNAL, TRUE); }

// Start flag (to mark the start of something)
#define INSTRUMENT_START_SIGNAL(x) {const char *cstr = [x UTF8String]; DTSendSignalFlag(cstr, DT_START_SIGNAL, TRUE); }

// End flag (to mark the end of something)
#define INSTRUMENT_END_SIGNAL(x) {const char *cstr = [x UTF8String]; DTSendSignalFlag(cstr, DT_END_SIGNAL, TRUE); }

What are these macros doing?

I’m converting the input x (NSString) to a C string using the convenience method UTF8String.  Credit for learning how to do this goes to the answers in the article How to convert NSString to C string?

I then call DTSendSignalFlag using the C string as the first arg. In order to be able to use my macros more than once and avoid a redefinition compiler warning for cstr, I wrap the macro contents in braces { }

Example of flag generation

Here’s an example of how to use my macros:

NSString *mystr = [NSString stringWithFormat:@"Loop index %d",arrIndex];

INSTRUMENT_POINT_SIGNAL(mystr)

Displaying the flags in your trace

As I discovered in the article Advanced Profiling With The DTPerformanceeSession Framework  you won’t be able to see the newly generated flags until you specifically enable them for display.  First go to the Manage Flags menu from Instruments:

ManageFlags

Next click on Displayed Flags and select Signal Flags (to put a check box next to it).  Note that the article above mentioned selecting Symbol Flags, but I found that I needed to check Signal Flags instead:

SignalFlags

You can see above that this management window allows you to see all the flags that you generated.  As you click on different flags, the dotted vertical cursor moves to that flag in the display.

As the first referenced article mentions, there is a point flag (shown above) as well as start and end flags (useful for selecting a range).

Advertisements

3 responses to “Using code generated flags to debug with Instruments

  1. Pingback: The development of Contacts2Web | Finalize.com: My journey with iOS and other code adventures

  2. Update 11/8/14: It appears that as of iOS 7 the use of DTSendSignalFlag is no longer functional and the Apple documentation on this is no longer available at: https://developer.apple.com/library/ios/documentation/AnalysisTools/Conceptual/WhatsNewInstruments/NewFeatures40/NewFeatures40.html

    Like

  3. Agreed. My question on this topic on Stack Overflow (http://stackoverflow.com/questions/19017843/dtsendsignalflag-in-ios-7) has received complete radio silence. I was hoping that the new, poorly documented Activity Tracing features (https://developer.apple.com/videos/wwdc/2014/?id=714) might fill this gap, but I don’t see any integration with Instruments. This ability to programmatically send flags was very useful and it’s frustrating that this is not addressed.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s