Archive for the ‘Unix’ Category

Logging in Leopard

Sunday, January 6th, 2008

The release of Leopard has given third-party developers a lot to do: attempting to restore features lost from Tiger, for instance. (By the way, where is the second party, and why am I never invited?) My friend Rainer Brockerhoff has provided a way, or Quay, to display hierarchical popup menus in the Dock again. One of my most missed features in Leopard is using NSLog to spew output exclusively to Xcode’s console log. When you debug or run your app in Xcode on Tiger, you can put NSLog calls everywhere without worrying about polluting console.log. In my opinion, console.log is only for important messages and errors. I frequently ask users to consult it if they’re experiencing a problem with an app. Either that or the Oracle at Delphi.

Leopard dispenses completely with console.log, though there is a “Console Messages” database query in Console. Whereas on Tiger stdout and stderr standardly go to console.log, on Leopard they boldly go to system.log (as well as to the “Console Messages” query). On either version of Mac OS X, Xcode redirects stdout and stderr to its own console log, so they don’t appear in Console at all.

According to the documentation, NSLog sends a message to stderr. This is true for Tiger, and it’s also true for Leopard, but Leopard’s NSLog has the additional behavior of sending a message to system.log regardless of whether stderr is redirected. Thus, when you debug or run your app in Xcode (these may amount to the same thing in Xcode 3), messages from NSLog appear both in Xcode’s console log and in system.log! Curiously, there is no duplication of NSLog messages in system.log when stderr is not redirected.

If you prefer to keep your debug output out of system.log, the workaround for this new NSLog behavior is to abandon NSLog for debugging purposes on Leopard. :-( After much experimentation with asl, I realized that our old faithful printf would work. Since printf writes to stdout, its output is redirected by Xcode. Plus, when you’re debugging your app in Xcode you don’t really need NSLog to tell you the name of your app, the date, or your shoe size.

A limitation of printf is that it doesn’t handle the format specifier %@ for an Objective-C object. With Cocoa, therefore, we want an Objective-C wrapper around printf (like, um, NSLog). If you add the following code to your target’s .pch file, you’ll have an Objective-C debug logging function JJLog available throughout your target’s code. To enable logging in your app’s debug build, just add JJLOGGING to the GCC_PREPROCESSOR_DEFINITIONS setting (AKA “Preprocessor Macros”) in the debug build configuration.


#ifdef __OBJC__
	#import <Cocoa/Cocoa.h>
	#ifdef JJLOGGING
		#define JJLog(...) (void)printf("%s:%i %s: %s\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, [[NSString stringWithFormat:__VA_ARGS__] UTF8String])
	#else
		#define JJLog(...)
	#endif
#endif

In your app’s release build, the debug function is a NOP that the compiler will almost certainly optimize out. This conditional code should not cause problems when using GCC_PRECOMPILE_PREFIX_HEADER, because Xcode already generates a separate precompiled prefix header for each build configuration. See the .pch.gch.hash-criteria files in /Library/Caches/com.apple.Xcode.###/SharedPrecompiledHeaders.

You can send gobs of gab to JJLog without repercussion or remorse. However, you’ll still want to use NSLog (sparingly, please) for runtime errors in your release build. Now to continue in the spirit of this post, I’ll redirect the epilogue to /dev/null.

Behind the firewall

Saturday, December 29th, 2007

Some people are apparently under the impression that firewall rules are the be-all and end-all of Mac OS X security. Deny all from any to me in. Before you spend days composing the perfect ipfw ruleset, however, take a look at sysctl. (You could spend days looking at sysctl.) One of the biggest misconceptions about Mac OS X — a misconception encouraged by the System Preferences UI — is that the firewall is not enabled out of the box. Nonsense!

net.inet.ip.fw.enable: 1

Admittedly, it’s a fairly flammable firewall (allow ip from any to any), but it’s enabled. More important, the default sysctl settings do provide at least a modest level of protection. For example:


net.inet.icmp.timestamp: 0
net.inet.icmp.maskrepl: 0

These prevent your machine from responding to ping -M time and ping -M mask requests. What time is it? Where the party at?

By Mac OS X herein I shall mean Leopard and Tiger. (Panther is not yet abandonware, but at this point it merely receives Christmas cards.) When you ‘start’ the firewall in System Preferences, Tiger adds a number of rules to ipfw. Leopard, on the other hand, includes a new Apple-designed firewall that mostly replaces ipfw. Though Leopard respects custom ipfw rulesets, it adds no rules to ipfw when you choose to block incoming connections. I don’t know much about how the Leopard firewall works; presumably it protects you somehow or other.

Leopard does still employ ipfw for “Stealth Mode”. If you turn that on, both Leopard and Tiger add the rule deny icmp from any to me in icmptypes 8. Curiously, Stealth mode prevents you from ‘pinging yourself’ in Leopard but not in Tiger. For fun (according to a rather loose definition of fun), try ping localhost. Somebody bring me a mirror! The difference in behavior is due to the Tiger-only rule allow ip from any to any via lo* that precedes all other rules.

Looking at the ipfw rules, you might think that Stealth Mode is overrated, like Notre Dame football and most wines over three dollars. If you want to learn its true value, you need to consult sysctl.


net.inet.tcp.blackhole: 2
net.inet.udp.blackhole: 1

With these settings, your computer mercilessly crushes attackers into singularities, as well as dropping their packets without response when sent to closed ports.

It would be nice if Bonjour wasn’t so talkative, broadcasting its greetings to your entire LAN. Bonjour also complains loudly when told to shut up by the firewall. On the other hand, you’re going to have to broadcast anyway for DHCP. Moreover, your LAN will see your internet traffic, especially on wireless.

Whoa, I suddenly realized after all these years that if you’re a grown man who lives in an attic, hangs out with high school students, has an ‘office’ in the bathroom, and is known for one syllable utterances, you’re not cool. You’re a loser.

WordPress Bug Fix: more props for me

Saturday, December 15th, 2007

Although I abhor self-promotion — much as Roger Federer abhors winning tournaments — someone must take on this thankless task. (I had to fire my publicist, because he had never heard of me.) Thus it is with great regret and sorrow that I announce my latest contribution to the WordPress open source project. It was just one minuscule twitch for mankind, yet one ginormous vault for a man, viz., yours truly.

Now some critics might claim that the security issue was trivial. In my defense, I would argue that critics are doo-doo heads. Except the ones in New York: they all love me.

Mac OS X 10.4.11: less tar

Thursday, December 6th, 2007

Although it seems late in the game to be adding new features to Tiger, Mac OS X 10.4.11 includes not only the high-profile Safari 3 update but also a few other interesting little additions. For instance, when you uncompress a .tar.gz file in Finder it no longer leaves behind a useless .tar that you have to manually trash. Neat!

Of course, it wouldn’t be Finder without some annoyance. The trade-off for un-cluttering your Desktop is up-cluttering your console.log:

BOMArchiveHelper[454] opened /Users/jeff/Desktop/.BAHEm7Xn/my-directory.tar

I’m not sure why they didn’t use tar xzf, which is approximately a billion times faster. Baby steps…