24
Jan
2009
 

Dropping NSLog in release builds

by Fraser Hess

NSLog() is a great tool that helps debugging efforts. Unfortunately it is expensive, especially on the iPhone, and depending on how it’s used or what you’re logging, it could leak sensitive or proprietary information. If you look around the web, you’ll find a few different ways to drop NSLog in your release builds. Here is what I’ve put together based on those.

First add the following to the <AppName>_Prefix.pch file in your Xcode project:

#ifdef DEBUG
#    define DLog(...) NSLog(__VA_ARGS__)
#else
#    define DLog(...) /* */
#endif
#define ALog(...) NSLog(__VA_ARGS__)

Right-click on your target and click Get Info. Select the Build tab. Make sure Configuration is set to Debug. Add -DDEBUG to the Other C Flags of your target.

And that’s about it. When you want to log only in debug builds use DLog(). In release builds DLog() will be compiled as an empty comment. Otherwise use ALog() for logging in both debug and release builds. (A as in always.)

I like this approach for a few reasons:

  1. Some approaches comment out all NSLog() statements when compiled. This approach lets me keep some logging if I want.
  2. Using ALog() and DLog(), I make a conscious choice about which builds I’m going to log in.
  3. There is very little setup.
  4. There is no overhead. Because DLog() is defined as NSLog(), executing DLog() is no different than executing NSLog()

If you’d like to replace NSLog with DLog in your source files, here’s a quick sed command that you can run in Terminal:
$ sed -i ".bak" 's/NSLog/DLog/' *.m
FYI, this will make a backup of each of the .m files whether it changed them or not.

Logging Sample Application

Comments

That can cause mysterious bugs or if you are lucky, a compile error when DEBUG is off because /* */ is not a statement. E.g. if (x) DLog(…). Instead, use do {} while (0) in place of the /* */

Excellent trick! But I don’t seems to have the “Other C Flags” section… I am in the Build tab of Debug-Config… Obviously I missed a tiny details, but which one?

Thx

Bernhard

Daniel Jalkut says:

Apple ships a tool which should be installed on most, if not all developers’ systems, called “tops.” It’s really just a slightly glorified sed-type tool, but it behaves in some sensible ways that would be harder to program in with sed. For example, it won’t replaces occurences of the symbol name in comments, etc.

Run something like this on your sources to see what it would do:

tops -dont replace “NSLog” with “DLog” *.m

Then take out the -dont if you’re happy with what you see ;)

Daniel

stompy says:

@Berhnard;

have a look here

jollyjinx says:

I’m using something similar, but more verbose for us developers. It’s also logging the instance and line numbers , class and method name. As described here:

http://www.jinx.de/teclog/2008.11.13.my-own-version-nslog-jlog.html

Jolly aka Patrick


author of: ScreenRecycler, JollysFastVNC, SmartSleep, SmartSokoban and more.

I’ve been doing something pretty similar, though my DLog (inside the #ifdef DEBUG) looks like:

#define DebugLog(s, …) NSLog((@”%s %s:%d ” s), __func__, basename(__FILE__), __LINE__, ## __VA_ARGS__);

Just some extra contextual information before the actual log statement. (This does, of course, lead to extra noise, which might end up causing more confusion in simple projects.)

Is there a good way to do this for iPhone development? There’s no way to pass an Other C flag that I can tell in an iPhone app target…

rgm says:

@garretmurray.net I scratched my head on this one for a while.

It turns out that if you have your build set to “Simulator | Debug” then the ‘Other C Flags’ setting will not show up. Set your project to “Device | Debug” and the flags setting will suddenly show up in the Build Settings.

Set it, then you can go back to “Simulator | Debug” and it appears to hold. I tested this on the 2.2.1 SDK.

yile says:

I am from cocoaChina forum, just a developer on iPhone.
Thank you, man!

Joel says:

CIMGF helped me out once again! I’d put off handling my NSLog problem way too long. Your approach is clear and effective. Thank you!

[...] was just one such approach in the Cocoa Is My Girlfriend site of DroppingNSLog in release builds but even a bit nicer was the actual debug output produced in Karl’s article: A drop-in [...]

[...] Is My Girlfriend?“Dropping NSLog in Release Build” : http://www.cimgf.com/2009/01/24/dropping-nslog-in-release-builds/ . [...]