<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lap Cat Software Blog &#187; Xcode</title>
	<atom:link href="http://lapcatsoftware.com/blog/category/xcode/feed/" rel="self" type="application/rss+xml" />
	<link>http://lapcatsoftware.com/blog</link>
	<description>Coding under the close supervision of cats</description>
	<lastBuildDate>Sat, 24 Jul 2010 13:30:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Local variables are free</title>
		<link>http://lapcatsoftware.com/blog/2009/12/19/local-variables-are-free/</link>
		<comments>http://lapcatsoftware.com/blog/2009/12/19/local-variables-are-free/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 16:30:13 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=236</guid>
		<description><![CDATA[This is part II of my irregularly scheduled series on compiler optimization. In part I, I explained how the compiler can optimize away return statements, resulting in missed breakpoints. My given workaround to that problem, though effective, was very ugly and architecture-dependent, much like Cowboys Stadium. (gdb) break *0x00001fc5 if $eax != 0 Although there&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>This is part II of my irregularly scheduled series on compiler optimization. In <a href="http://lapcatsoftware.com/blog/2009/11/16/why-did-my-breakpoint-not-get-hit/" title="Why did my breakpoint not get hit?">part I</a>, I explained how the compiler can optimize away <code>return</code> statements, resulting in missed breakpoints. My given workaround to that problem, though effective, was very ugly and architecture-dependent, much like Cowboys Stadium.</p>
<pre><code>(gdb) break *0x00001fc5 if $eax != 0</code></pre>
<p>Although there&#8217;s not much we can do to prevent the compiler optimization, we can greatly simplify our conditional breakpoint. I had suggested rewriting the source code, which was awe-inspiringly prescient, because that&#8217;s what I&#8217;m going to do now. Here&#8217;s the original code:</p>
<pre><code>8	if (ShouldReturn())
9		return;</code></pre>
<p>And here&#8217;s the revised code:</p>
<pre><code>8	int localVar = ShouldReturn();
9	if (localVar)
10		return;</code></pre>
<p>The <code>return</code> at line 10 will still be optimized away. However, the revised code allows us to set a simple breakpoint at line 9 that will stop when we want:</p>
<pre><code>(gdb) break 9 if localVar != 0</code></pre>
<p>No knowledge of the architecture, machine registers, or assembly language is required.</p>
<p>From the beginning of time (January 1970, of course), programmers have struggled over coding style. Objective-C programmers, for example, expend undue effort arranging their brackets. (I have <code>[NSMutableArray array]</code> going to the Final Four.) For some, bracket-making becomes a kind of game or contest.</p>
<pre><code>[[[[[[[[[[[[[See how] many] method] calls] we] can] fit] on] one] line] of] source] code];</code></pre>
<p>I&#8217;ve changed my coding style over the years, but I&#8217;ve settled on one fundamental principle: write your code so that it&#8217;s easy to debug. All your fancy margin-aligning isn&#8217;t going to help when you need to figure out why your app keeps exploding. If you have nested method calls on one line of code, you can&#8217;t easily set a breakpoint in the middle. That&#8217;s why I prefer as much as possible to have only one method call per line of code, and create a local variable to store the return value.</p>
<p>There is a misconception that local variables are expensive, in terms of either computation or memory. The truth is that local variables are very cheap, the value meals of the computing world. (Would you like trans fat with your saturated fat?) It only takes one machine instruction to store a pointer address to a local variable. One machine instruction is really quite fast, about as fast as you can get &mdash; at least with restrictor plates. With regard to memory, local variables only take up stack space. To create a local variable, you simply move the stack a little. When the method or function returns, the stack is moved back, and thereby the space reserved for local variables is automatically recovered. Of course, you don&#8217;t want to create large C arrays on the stack, but a pointer to an Objective-C object only takes 4 bytes on the stack for 32-bit, 8 bytes for 64-bit. The default 32-bit stack size is 8MB, so you&#8217;re not going to run out of space unless you have deeply recursive calls.</p>
<p>Even these small costs are only relevant in the context of your app&#8217;s unoptimized, debug configuration. For your customers, on the other hand, local variables are free. As in Mumia, or Bird. When you compile your app using the release configuration, the local variables disappear, the compiler optimizes them away. (By the way, this is one of the reasons that debugging the release build of your app can be a frustrating and/or wacky experience.) To see the optimization in action, let&#8217;s consider some sample code:</p>
<pre><code>1  #import &lt;Foundation/Foundation.h&gt;
2
3  @interface MyObject : NSObject {}
4  @end
5
6  @implementation MyObject
7
8  -(NSString *)myDirectProcessName {
9  	return [[[NSProcessInfo processInfo] processName] lowercaseString];
10 }
11
12 -(NSString *)myRoundaboutProcessName {
13 	NSString *myRoundaboutProcessName = nil;
14 	NSProcessInfo *processInfo = [NSProcessInfo processInfo];
15 	NSString *processName = [processInfo processName];
16 	NSString *lowercaseString = [processName lowercaseString];
17 	myRoundaboutProcessName = lowercaseString;
18 	return myRoundaboutProcessName;
19 }
20
21 @end
22
23 int main(int argc, const char *argv[]) {
24 	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
25 	MyObject *myObject = [[[MyObject alloc] init] autorelease];
26 	NSLog(@"My direct process name: %@", [myObject myDirectProcessName]);
27 	NSLog(@"My roundabout process name: %@", [myObject myRoundaboutProcessName]);
28 	[pool release];
29 	return 0;
30 }</code></pre>
<p>The above code is obviously contrived and useless. It only has value for explanatory purposes, and perhaps in the app store for $0.99. The methods <code>-myRoundaboutProcessName</code> and <code>-myDirectProcessName</code> do the same thing, the former with and the latter without local variables. Here&#8217;s the i386 disassembly for the methods when compiled using the debug configuration:</p>
<pre><code>-[MyObject myDirectProcessName]:
00001d2a	nop
00001d2b	nop
00001d2c	nop
00001d2d	nop
00001d2e	nop
00001d2f	nop
00001d30	pushl	%ebp
00001d31	movl	%esp,%ebp
00001d33	pushl	%ebx
00001d34	subl	$0x14,%esp
00001d37	calll	0x00001d3c
00001d3c	popl	%ebx
00001d3d	leal	0x000012e8(%ebx),%eax
00001d43	movl	(%eax),%eax
00001d45	movl	%eax,%edx
00001d47	leal	0x000012e4(%ebx),%eax
00001d4d	movl	(%eax),%eax
00001d4f	movl	%eax,0x04(%esp)
00001d53	movl	%edx,(%esp)
00001d56	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001d5b	movl	%eax,%edx
00001d5d	leal	0x000012e0(%ebx),%eax
00001d63	movl	(%eax),%eax
00001d65	movl	%eax,0x04(%esp)
00001d69	movl	%edx,(%esp)
00001d6c	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001d71	movl	%eax,%edx
00001d73	leal	0x000012dc(%ebx),%eax
00001d79	movl	(%eax),%eax
00001d7b	movl	%eax,0x04(%esp)
00001d7f	movl	%edx,(%esp)
00001d82	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001d87	addl	$0x14,%esp
00001d8a	popl	%ebx
00001d8b	leave
00001d8c	ret
-[MyObject myRoundaboutProcessName]:
00001d8d	nop
00001d8e	nop
00001d8f	nop
00001d90	nop
00001d91	nop
00001d92	nop
00001d93	pushl	%ebp
00001d94	movl	%esp,%ebp
00001d96	pushl	%ebx
00001d97	subl	$0x24,%esp
00001d9a	calll	0x00001d9f
00001d9f	popl	%ebx
00001da0	movl	$0x00000000,0xe8(%ebp)
00001da7	leal	0x00001285(%ebx),%eax
00001dad	movl	(%eax),%eax
00001daf	movl	%eax,%edx
00001db1	leal	0x00001281(%ebx),%eax
00001db7	movl	(%eax),%eax
00001db9	movl	%eax,0x04(%esp)
00001dbd	movl	%edx,(%esp)
00001dc0	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001dc5	movl	%eax,0xec(%ebp)
00001dc8	movl	0xec(%ebp),%edx
00001dcb	leal	0x0000127d(%ebx),%eax
00001dd1	movl	(%eax),%eax
00001dd3	movl	%eax,0x04(%esp)
00001dd7	movl	%edx,(%esp)
00001dda	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001ddf	movl	%eax,0xf0(%ebp)
00001de2	movl	0xf0(%ebp),%edx
00001de5	leal	0x00001279(%ebx),%eax
00001deb	movl	(%eax),%eax
00001ded	movl	%eax,0x04(%esp)
00001df1	movl	%edx,(%esp)
00001df4	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001df9	movl	%eax,0xf4(%ebp)
00001dfc	movl	0xf4(%ebp),%eax
00001dff	movl	%eax,0xe8(%ebp)
00001e02	movl	0xe8(%ebp),%eax
00001e05	addl	$0x24,%esp
00001e08	popl	%ebx
00001e09	leave
00001e0a	ret</code></pre>
<p>As expected, <code>-myRoundaboutProcessName</code> makes more room on the stack than <code>-myDirectProcessName</code>:</p>
<pre><code>00001d34	subl	$0x14,%esp
00001d97	subl	$0x24,%esp</code></pre>
<p>At <code>00001da0</code>, <code>-myRoundaboutProcessName</code> sets the value of the local variable to <code>nil</code>, as in line 13 of the source code. The interesting differences, though, are immediately after the calls to <code>objc_msgSend()</code>. By the standard ABI, the register <code>eax</code> contains the return value of <code>objc_msgSend()</code>. In <code>-myDirectProcessName</code>, the value in <code>eax</code> is simply moved to the register <code>edx</code>:</p>
<pre><code>00001d5b	movl	%eax,%edx</code></pre>
<p>In contrast, <code>-myRoundaboutProcessName</code> first stores the value on the stack before moving it to <code>edx</code>. The address on the stack is the space reserved for the local variable:</p>
<pre><code>00001dc5	movl	%eax,0xec(%ebp)
00001dc8	movl	0xec(%ebp),%edx</code></pre>
<p>After the final <code>objc_msgSend()</code> call, <code>-myDirectProcessName</code> doesn&#8217;t bother to do much, because the return value in <code>eax</code> will become the return value of the whole method. In <code>-myRoundaboutProcessName</code>, it needs to store values in local variables as in lines 16 and 17 of the source code:</p>
<pre><code>00001df9	movl	%eax,0xf4(%ebp)
00001dfc	movl	0xf4(%ebp),%eax
00001dff	movl	%eax,0xe8(%ebp)
00001e02	movl	0xe8(%ebp),%eax</code></pre>
<p>So that&#8217;s how the methods differ in the unoptimized build. Now let&#8217;s see what happens when we use the release configuration. Here&#8217;s the optimized disassembly for <code>-myDirectProcessName</code>:</p>
<pre><code>-[MyObject myDirectProcessName]:
00001dce	pushl	%ebp
00001dcf	movl	%esp,%ebp
00001dd1	subl	$0x18,%esp
00001dd4	movl	0x00003000,%eax
00001dd9	movl	%eax,0x04(%esp)
00001ddd	movl	0x0000302c,%eax
00001de2	movl	%eax,(%esp)
00001de5	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001dea	movl	0x00003004,%edx
00001df0	movl	%edx,0x04(%esp)
00001df4	movl	%eax,(%esp)
00001df7	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001dfc	movl	0x00003008,%edx
00001e02	movl	%edx,0x0c(%ebp)
00001e05	movl	%eax,0x08(%ebp)
00001e08	leave
00001e09	jmpl	0x0000400a	; symbol stub for: _objc_msgSend</code></pre>
<p>The optimized method is significantly shorter, as expected from the compiler option <code>-Os</code>. First, you&#8217;ll notice that all those pesky <code>nop</code> instructions have been deleted. Stallman put them in unoptimized builds just to annoy us. (Or they may have been for Fix and Continue, but I always assume the worst.) There are additional optimizations as well that I won&#8217;t belabor here, because I&#8217;m eager to get to the climax. (Sorry, dear.) For your enlightenment and enjoyment, here&#8217;s the optimized disassembly for <code>-myRoundaboutProcessName</code>:</p>
<pre><code>-[MyObject myRoundaboutProcessName]:
00001e0e	pushl	%ebp
00001e0f	movl	%esp,%ebp
00001e11	subl	$0x18,%esp
00001e14	movl	0x00003000,%eax
00001e19	movl	%eax,0x04(%esp)
00001e1d	movl	0x0000302c,%eax
00001e22	movl	%eax,(%esp)
00001e25	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001e2a	movl	0x00003004,%edx
00001e30	movl	%edx,0x04(%esp)
00001e34	movl	%eax,(%esp)
00001e37	calll	0x0000400a	; symbol stub for: _objc_msgSend
00001e3c	movl	0x00003008,%edx
00001e42	movl	%edx,0x0c(%ebp)
00001e45	movl	%eax,0x08(%ebp)
00001e48	leave
00001e49	jmpl	0x0000400a	; symbol stub for: _objc_msgSend</code></pre>
<p>Identical! Ah, that&#8217;s nice. Smoke &#8216;em if you got &#8216;em.</p>
<p>In conclusion, feel free to sprinkle, pepper, dash, or even drown your code with local variables. And with the engineering hours of debugging time you save, get me a nice (not free) present. I&#8217;m partial to flavored coffee and unflavored MacBooks.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/12/19/local-variables-are-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why did my breakpoint not get hit?</title>
		<link>http://lapcatsoftware.com/blog/2009/11/16/why-did-my-breakpoint-not-get-hit/</link>
		<comments>http://lapcatsoftware.com/blog/2009/11/16/why-did-my-breakpoint-not-get-hit/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:04:33 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=228</guid>
		<description><![CDATA[This is part I of a II+ (take that, trademark trolls) part series on compiler optimization. For the gcc compiler, you can specify the level of optimization with various -O options. The default for compiling is -O0, which means do not optimize. As we shall see, however, the compiler always optimizes to an extent. That [...]]]></description>
			<content:encoded><![CDATA[<p>This is part I of a II+ (take that, trademark trolls) part series on compiler optimization. For the <code>gcc</code> compiler, you can specify the level of optimization with various <code>-O</code> options. The default for compiling is <code>-O0</code>, which means do not optimize. As we shall see, however, the compiler always optimizes to an extent. That is to say, <code>gcc -O0</code>, you lie!</p>
<p>The primary reason for using the <code>-O0</code> option (besides to avoid compiler optimization bugs) is to facilitate debugging of your code. With higher levels of optimization, the compiler is given more freedom to &#8216;ignore&#8217; your source code in writing machine instructions, as long as the results are the same. Although it is possible to debug optimized binaries, the experience is often confusing and unhelpful for the programmer (much like reading cocoa-dev). Turning off optimization gives the closest correlation between source code and machines instructions. Yet even with no optimization, the correlation is not perfect, and this can lead to debugging problems.</p>
<p>Let&#8217;s consider a simple example:</p>
<pre><code>$ cat &gt; returnbreak.c
#include &lt;stdio.h&gt;

int ShouldReturn(void) {
	return 1;
}

void HelloWorld(void) {
	if (ShouldReturn())
		return;

	printf("Hello, World!\n");
}

int main(int argc, const char *argv[]) {
	HelloWorld();
	return 0;
}
$ gcc -g -O0 -o returnbreak returnbreak.c
$ gdb returnbreak
GNU gdb 6.3.50-20050815 (Apple version gdb-966) (Tue Mar 10 02:43:13 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries ... done

(gdb) list HelloWorld
2
3	int ShouldReturn(void) {
4		return 1;
5	}
6
7	void HelloWorld(void) {
8		if (ShouldReturn())
9			return;
10
11		printf("Hello, World!\n");
(gdb) break 9
Breakpoint 1 at 0x1fc9: file returnbreak.c, line 9.
(gdb) run
Starting program: /Users/jeff/Desktop/returnbreak
Reading symbols for shared libraries ++. done

Program exited normally.</code></pre>
<p>WTF?!? Why did my breakpoint not get hit?</p>
<pre><code>(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x00001fc9 in HelloWorld at returnbreak.c:9</code></pre>
<p>Hmm, that seems ok. Let&#8217;s try something else.</p>
<pre><code>(gdb) break HelloWorld
Breakpoint 2 at 0x1fc0: file returnbreak.c, line 8.
(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x00001fc9 in HelloWorld at returnbreak.c:9
2   breakpoint     keep y   0x00001fc0 in HelloWorld at returnbreak.c:8
(gdb) run
Starting program: /Users/jeff/Desktop/returnbreak 

Breakpoint 2, HelloWorld () at returnbreak.c:8
8		if (ShouldReturn())
(gdb) c
Continuing.

Program exited normally.</code></pre>
<p>Odd, it hits the breakpoint at line 8 but not at line 9. The breakpoint on line 9 is at address <code>0x00001fc9</code>, so let&#8217;s look at the (i386) disassembly for that:</p>
<pre><code>(gdb) disassemble 0x00001fc9
Dump of assembler code for function HelloWorld:
0x00001fb3 &lt;HelloWorld+0&gt;:	push   %ebp
0x00001fb4 &lt;HelloWorld+1&gt;:	mov    %esp,%ebp
0x00001fb6 &lt;HelloWorld+3&gt;:	push   %ebx
0x00001fb7 &lt;HelloWorld+4&gt;:	sub    $0x14,%esp
0x00001fba &lt;HelloWorld+7&gt;:	call   0x1fbf &lt;HelloWorld+12&gt;
0x00001fbf &lt;HelloWorld+12&gt;:	pop    %ebx
0x00001fc0 &lt;HelloWorld+13&gt;:	call   0x1fa6 &lt;ShouldReturn&gt;
0x00001fc5 &lt;HelloWorld+18&gt;:	test   %eax,%eax
0x00001fc7 &lt;HelloWorld+20&gt;:	jne    0x1fd7 &lt;HelloWorld+36&gt;
0x00001fc9 &lt;HelloWorld+22&gt;:	lea    0x30(%ebx),%eax
0x00001fcf &lt;HelloWorld+28&gt;:	mov    %eax,(%esp)
0x00001fd2 &lt;HelloWorld+31&gt;:	call   0x3005 &lt;dyld_stub_puts&gt;
0x00001fd7 &lt;HelloWorld+36&gt;:	add    $0x14,%esp
0x00001fda &lt;HelloWorld+39&gt;:	pop    %ebx
0x00001fdb &lt;HelloWorld+40&gt;:	leave
0x00001fdc &lt;HelloWorld+41&gt;:	ret
End of assembler dump.</code></pre>
<p>When <code>ShouldReturn()</code> returns, the return value is in the register <code>eax</code>. The <code>test</code> instruction at <code>0x00001fc5</code> performs a bitwise AND of the two operands &mdash; which in this case are the same. If the result is non-zero &mdash; and in this case the result is 1 &mdash; the Zero Flag in the <code>EFLAGS</code> register is set to 0. This instruction corresponds to evaluating the conditional on line 8 of our source code. Then the <code>jne</code> instruction at <code>0x00001fc7</code> jumps to a certain address if the Zero Flag is 0. In our source code, the flow of control should move to the <code>return</code> statement on line 9 when the conditional evaluates to non-zero. According to the machine instructions, on the other hand, it jumps to <code>0x1fd7</code> when the conditional evaluates to non-zero. This address is the beginning of the standard function epilog, which restores the stack and registers to their previous state before returning.</p>
<p>The problem here is that while the function <code>HelloWorld()</code> has two exit points in our source code, it only has one exit point in the machine instructions. In essence, the compiler has optimized for size, despite our use of the <code>-O0</code> option. Given the generated machine instructions, there is nowhere to put a breakpoint that will only be hit when the conditional at line 8 evaluates to non-zero. A breakpoint at <code>0x00001fc5</code> or <code>0x00001fc7</code> would be hit whenever the conditional is evaluated, which is always. A breakpoint at <code>0x00001fd7</code> would be hit whenever the function returns, which is always as well. Unfortunately, <code>gdb</code> places the breakpoint at <code>0x00001fc9</code>, which is actually the opposite of what we intended, because it only gets hit when the conditional evaluates to zero. This is why the program exits normally without ever hitting the breakpoint. I consider this to be a bug in <code>gdb</code>; it would be better, I think, if it would just fail and give an error when we try to set the breakpoint. Of course, it may be a bug in <code>gcc</code> that it optimizes away our multiple exit points with optimization off. But hey, what do you expect from free software?</p>
<p>There are several workarounds for this problem. One would be to re-write your source code. (No, that&#8217;s not a joke. See Part II of this series.) Another workaround, if you only want to break on the result of a conditional, is to use a conditional breakpoint:</p>
<pre><code>(gdb) delete break
Delete all breakpoints? (y or n) y
(gdb) break *0x00001fc5 if $eax != 0
Breakpoint 1 at 0x1fc5: file returnbreak.c, line 8.
(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x00001fc5 in HelloWorld at returnbreak.c:8
	stop only if $eax != 0
(gdb) run
Starting program: /Users/jeff/Desktop/returnbreak 

Breakpoint 1, 0x00001fc5 in HelloWorld () at returnbreak.c:8
8		if (ShouldReturn())
(gdb) c
Continuing.

Program exited normally.</code></pre>
<p>To summarize, if you find that your breakpoints are not getting hit, you now know who to blame. Namely, yourself. It&#8217;s almost certain that your Xcode project settings are wrong.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/11/16/why-did-my-breakpoint-not-get-hit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Radar Bug Friday: Bonus Edition</title>
		<link>http://lapcatsoftware.com/blog/2009/03/13/radar-bug-friday-bonus-edition/</link>
		<comments>http://lapcatsoftware.com/blog/2009/03/13/radar-bug-friday-bonus-edition/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 15:15:51 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=126</guid>
		<description><![CDATA[Though Apple Bug Friday has gone the way of Rip and Robert Van Winkle, I&#8217;m bringing it back for one last, glorious, remunerative show. Opening act: some weird dancing fool who people last admired in the 80s. Take your choice. The continuing failure of Apple to provide a searchable bug database has forced developers to [...]]]></description>
			<content:encoded><![CDATA[<p>Though Apple Bug Friday has gone the way of Rip and Robert Van Winkle, I&#8217;m bringing it back for one last, glorious, remunerative show. Opening act: some weird dancing fool who people last admired in the 80s. Take your choice.</p>
<p>The continuing failure of Apple to provide a searchable bug database has forced developers to take matters into their own hands. Witness <a href="http://openradar.appspot.com/" title="Open Radar">Open Radar</a>. I&#8217;ve never been one to join any club that would have me as a member &mdash; nor have I been one to be invited to any clubs &mdash; so I&#8217;ve decided to host <a href="http://lapcatsoftware.com/rdar/index.html" title="Radar Problems">my own list of bugs.</a> Keep in mind that these are not all of the Radar bugs I&#8217;ve ever filed. They&#8217;re not even all of my currently unfixed bugs. They are, however, a very large subset of my currently unfixed bugs. (I&#8217;d say the cardinality is somewhere between aleph-null and aleph-one.)</p>
<p>For legal, moral, and comical reasons, I&#8217;ve edited the bugs to remove confidential information. I&#8217;ve also left out the embarrassing nude photos I attach for ADC. (I would stop uploading them, but engineering always requests more.) I hope that you find these bugs useful and also enjoy reading them as much as I enjoyed writing them. In fact, it&#8217;s a metaphysical certainty that you will enjoy reading them at least that much.</p>
<p>After imparting this vital information, I leave you to go in, through, and beyond &hellip; for coffee and a donut.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/03/13/radar-bug-friday-bonus-edition/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>dSYM in your bundle or just happy to see me</title>
		<link>http://lapcatsoftware.com/blog/2009/01/20/dsym-in-your-bundle-or-just-happy-to-see-me/</link>
		<comments>http://lapcatsoftware.com/blog/2009/01/20/dsym-in-your-bundle-or-just-happy-to-see-me/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 15:15:36 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=111</guid>
		<description><![CDATA[It&#8217;s been a while since I posted last. Rest assured that I did survive the Y2K9 disaster, though not unscathed. Since bloggers and other entertainers &#8212; such as Brian Williams &#8212; are required by law to offer a retrospective at the end of a year, I&#8217;ve been scanning the Top 10 lists of Top 10 [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I posted last. Rest assured that I did survive the Y2K9 disaster, though not unscathed. Since bloggers and other entertainers &mdash; such as Brian Williams &mdash; are required by law to offer a retrospective at the end of a year, I&#8217;ve been scanning the Top 10 lists of Top 10 lists of things that we have gained and lost in 2008. Next to our collective sanity, the most significant loss of the year was <a href="http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/" title="Stabs is deprecated">STABS</a>. Actually, it wasn&#8217;t so much lost as deprecated. This means that we can&#8217;t expect any new features (or bugs!), and support for STABS debugging symbols may disappear in some future operating system, say, Windows -400. (I assume that the countdown of version numbers from 95 to 7 is intended to accurately represent the software&#8217;s regression.) In the transition from STABS to DWARF, it was thought (by the people who matter, viz., me) that we also lost the ability to ship debugging symbols with our apps. Luckily, it was discovered (again, by the people who matter) that we did not lose this ability.</p>
<p>Developers sometimes need to give users a debug version of an application. For example, a user may be experiencing an exception or crash that the developer cannot reproduce. Including debugging symbols with the app allows the reports to be fully symbolized. With STABS, the symbols reside within the app&#8217;s executable, so shipping them is trivial. The DWARF with dSYM format, on the other hand, puts the debugging symbols in a separate file. (To be accurate, a separate file within a separate bundle, but we&#8217;ll ignore that fact for this sentence.) By default, Xcode creates <code>MyApp.app.dSYM</code> in the same folder as <code>MyApp.app</code>, and indeed, Leopard&#8217;s crash reporter can locate <code>MyApp.app.dSYM</code> in the same folder as <code>MyApp.app</code> regardless of which folder they&#8217;re in on disk. Theoretically, then, you could have the user put a <code>.dSYM</code> in the same folder as the app. However, making the user do this would be, in a word, lame. In two words, pretty lame. Moreover, it doesn&#8217;t work at all on Tiger. Pretty, pretty lame.</p>
<p>When I face an insoluble problem, my tendency is to step back and get philosophical. Why do I exist? Why does the universe hate me? Who was the real Darrin? More to the point: what is an app? Essentially, an app is a command-line tool in a box with a pretty bow. (Another iSweater, just what I needed!) An app&#8217;s main executable file is located in the directory <code>Contents/MacOS</code> of the <code>.app</code> bundle. You can even launch an app from the command line, e.g.,</p>
<pre><code>/Applications/Safari.app/Contents/MacOS/Safari</code></pre>
<p>assuming that you haven&#8217;t deleted Safari for security reasons. So how does this information help us? It doesn&#8217;t &mdash; I&#8217;m just killing time here. However, it&#8217;s worth noting that if you build the Release configuration of a command-line tool project, Xcode by default creates <code>MyTool.dSYM</code> in the same folder as <code>MyTool</code>. In both Leopard and Tiger, the crash reporter can locate the <code>.dSYM</code> there. Thus, you would expect that the crash reporter can also locate <code>MyApp.app/Contents/MacOS/MyApp.dSYM</code> when your app crashes. And you would be right! (Of course, you would expect this because I just told you, whereas originally you would have expected to try a bunch of stuff and fail, like putting <code>MyApp.app.dSYM</code> in <code>MyApp.app/Contents/MacOS</code>.)</p>
<p>The beauty of this technique is that it works not only for the app&#8217;s main executable but also for other embedded executables such dynamic libraries and frameworks. When a crash occurs involving <code>MyFramework.framework</code>, the crash reporter will find</p>
<pre><code>MyApp.app/Contents/Frameworks/MyFramework.framework/Versions/A/MyFramework.dSYM</code></pre>
<p>You can build the framework in a separate Xcode project and copy the product along with its embedded <code>dSYM</code> into your app&#8217;s bundle, and the symbols will be found at crashtime. (That&#8217;s runtime with a bang.) In Tiger, the line numbers of the source code files can sometimes be a little off in the crash reports; this may be due to bugs in the handling of stripped binaries by <code>atos</code>, which I mentioned in my <a href="http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/" title="Stabs is deprecated">earlier post</a>.</p>
<p>Now that we know where to put the debugging symbols in the app bundle, how do we get them there? Manual copying is unthinkable (like giving David Pogue a copy of OS X GM before ADC members, or putting Leon Panetta in charge of the CIA). If your entire build process is not automated, you should give up software development immediately and look for another career; I recommend professional ice dancing. You could write a shell script to copy <code>MyApp.app.dSYM</code> from the <code>build</code> directory, but that&#8217;s only slightly less annoying than having your users copy it to <code>/Applications</code>, because it&#8217;s something that Xcode should do itself.</p>
<p>Fortunately, the  <a href="http://developer.apple.com/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/100-Build_Setting_Reference/build_setting_ref.html" title="Xcode Build Setting Reference">Xcode build setting reference</a> tells us how to configure this. Or so one <a href="http://developer.apple.com/search.php?q=DWARF_DSYM_FOLDER_PATH" title="No Results Found">would think</a>. Well, at least the relevant build settings are found in the environment variables &hellip; after you&#8217;ve written your shell script. The Xcode build transcript normally doesn&#8217;t show environment variables, but you can add a run script build phase to your target and check the option &#8220;Show environment variables in build log&#8221;. The environment variables reveal the default values for <code>DWARF_DSYM_FOLDER_PATH</code> and <code>DWARF_DSYM_FILE_NAME</code>, which Xcode uses in creating the <code>dSYM</code> file. Although you won&#8217;t find them in the target&#8217;s list of build settings, you can create them yourself in the User-Defined section. To embed the <code>dSYM</code> within the app bundle, just set <code>DWARF_DSYM_FOLDER_PATH</code> to <code>$(CONFIGURATION_BUILD_DIR)/$(EXECUTABLE_FOLDER_PATH)</code> and <code>DWARF_DSYM_FILE_NAME</code> to <code>$(EXECUTABLE_NAME).dSYM</code>. These settings should work for both apps and frameworks.</p>
<p>My beard has grown longer over the course of this post, and my knees are starting to ache, so it&#8217;s time to wrap it up, tip my hat to the new year, and meet the new boss.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/01/20/dsym-in-your-bundle-or-just-happy-to-see-me/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stabs is deprecated</title>
		<link>http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/</link>
		<comments>http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 15:09:54 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/</guid>
		<description><![CDATA[This post is dedicated to E. Gary Gygax, the second greatest corrupter of youth in history. It&#8217;s about D&#38;D, that is, DWARF and dSYM. As of 2008-02-27, the STABS debugging symbols format has been deprecated by Apple. The default value for the DEBUG_INFORMATION_FORMAT build setting in Xcode projects had been stabs, but now it&#8217;s time [...]]]></description>
			<content:encoded><![CDATA[<p>This post is dedicated to E. Gary Gygax, the second greatest corrupter of youth in history. It&#8217;s about D&amp;D, that is, DWARF and dSYM. As of 2008-02-27, the STABS debugging symbols format has been <a href="http://developer.apple.com/technotes/tn2004/tn2123.html" title="Technical Note TN2123: CrashReporter">deprecated by Apple</a>. The default value for the <code>DEBUG_INFORMATION_FORMAT</code> build setting in Xcode projects had been <code>stabs</code>, but now it&#8217;s time to move on. (I&#8217;m talking to you, Justin Long.) Our other options are <code>dwarf</code> or <code>dwarf-with-dsym</code>. Also <code>cake</code> or <code>death</code>.</p>
<p>With STABS, you could build the release version of your app with debugging symbols, make a copy of the executable <code>MyApp.app/Contents/MacOS/MyApp</code> to keep, strip the executable for shipping, and then use the unstripped executable for symbolizing crash reports by giving a space-separated list of stack trace addresses to the command-line tool <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/atos.1.html" title="man atos">atos</a>. Unfortunately, <code>atos</code> cannot currently serve this purpose with DWARF. Unlike STABS, DWARF does not include the debugging symbols in the executable itself but merely includes references to the intermediate object files, which do contain debugging symbols. You can usually find these <code>.o</code> files in a sub-directory of the <code>build/MyApp.build</code> directory. If you delete the object files after building with <code>dwarf</code>, you won&#8217;t be able to step through your app&#8217;s code. (With <code>stabs</code>, the object files are refuse.) You also won&#8217;t be able to step through the code if you strip debugging symbols from your app, even if you keep the object files, because the references to the object files will be gone from the executable.</p>
<p>To avoid losing the debugging symbols for your app after stripping, you want to use the option <code>dwarf-with-dsym</code>. The DWARF with dSYM option performs an additional step beyond ordinary DWARF: it creates a separate <code>MyApp.app.dSYM</code> file that contains all of the debugging symbols for your app. In fact, the DWARF with dSYM option allows you to step through your code regardless of whether the executable is stripped! This is possible because <code>gdb</code> will look for the <code>.dSYM</code> file in the same directory as your app. It doesn&#8217;t need to know the name or location of the object files. If you don&#8217;t strip debugging symbols, you can use either the <code>.o</code> files or the <code>.dSYM</code> file for debugging, but for the local debug build of your app there&#8217;s no point in using dSYM, since that would just prolong your build time. You have better things to do than wait for builds, such as writing comments on <a href="http://slashdot.org/" title="NEWS FOR NERDS. STUFF THAT MATTERS.">Slashdot</a>.</p>
<p>The trouble with <code>atos</code> is that it does not reliably find debugging information in <code>.dSYM</code> files for stripped executables. Although Apple&#8217;s documentation (as of 2007-04-02) <a href="http://developer.apple.com/tools/xcode/symbolizingcrashdumps.html" title="Debugging and Symbolizing Crash Dumps in Xcode">says</a>, &#8220;If you&#8217;re using DWARF <code>dSYM</code> files, you must be using the version of <code>atos</code> included in Xcode 3 (Mac OS X version 10.5)&#8221;, Apple&#8217;s engineers <a href="http://lists.apple.com/archives/Xcode-users/2008/Feb/msg00525.html" title="Re: Symbolizing Crash Dump with atos. How does it get the .dSYM?">say</a>, &#8220;The underlying framework that atos uses doesn&#8217;t support loading symbol names from dSYM files in Leopard.&#8221; In my testing, however, there doesn&#8217;t seem to be a difference between Leopard and Tiger, at least not with Xcode 2.5 on Tiger. On both Leopard and Tiger, <code>atos</code> successfully loads symbol names from <code>.dSYM</code> files (I deleted the <code>.o</code> files) for unstripped executables. For stripped executables, in contrast, <code>atos</code> frequently fails to load the symbol names, or even gives inaccurate results.</p>
<p>The CrashReporter Technical Note suggests loading your app and its <code>.dSYM</code> in <code>gdb</code> to translate stack trace addresses from crash reports. That&#8217;s like having to start your car in order to read the odometer. (Oh wait, I have to do that, Nissan!) An alternative method is the command-line tool <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/dwarfdump.1.html" title="man dwarfdump">dwarfdump</a>. It requires only the <code>.dSYM</code> file, not a copy of your app, and its <code>--lookup</code> option will do the same job as <code>gdb</code> without the overhead.</p>
<p>Please note that by breathing, blinking, or moving at all, even to command-w this page, you thereby register your agreement not to disclose or discuss this information anywhere with anyone at any time, no matter the duress, torture, or water-boarding you may undergo to extract it. This agreement holds despite the fact that the information is publicly available on the internet for every person in the world to read. Failure to uphold this agreement will result in multiple, painful cat scratches, in certain cases leading to cat scratch fever.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Logging in Leopard</title>
		<link>http://lapcatsoftware.com/blog/2008/01/06/logging-in-leopard/</link>
		<comments>http://lapcatsoftware.com/blog/2008/01/06/logging-in-leopard/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 15:08:35 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/2008/01/06/logging-in-leopard/</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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 <a href="http://brockerhoff.net/" title="Finely crafted software for the Macintosh by Rainer Brockerhoff">Rainer Brockerhoff</a> has provided a way, or <a href="http://brockerhoff.net/quay/" title="Quay.app">Quay</a>, to display hierarchical popup menus in the Dock again. One of my most missed features in Leopard is using <code>NSLog</code> to spew output exclusively to Xcode&#8217;s console log.  When you debug or run your app in Xcode on Tiger, you can put <code>NSLog</code> calls everywhere without worrying about polluting <code>console.log</code>. In my opinion, <code>console.log</code> is only for important messages and errors. I frequently ask users to consult it if they&#8217;re experiencing a problem with an app. Either that or the Oracle at Delphi.</p>
<p>Leopard dispenses completely with <code>console.log</code>, though there is a &#8220;Console Messages&#8221; database query in Console. Whereas on Tiger <code>stdout</code> and <code>stderr</code> standardly go to <code>console.log</code>, on Leopard they boldly go to <code>system.log</code> (as well as to the &#8220;Console Messages&#8221; query). On either version of Mac OS X, Xcode redirects <code>stdout</code> and <code>stderr</code> to its own console log, so they don&#8217;t appear in Console at all.</p>
<p>According to the <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSLog" title="Foundation Functions Reference">documentation</a>, <code>NSLog</code> sends a message to <code>stderr</code>. This is true for Tiger, and it&#8217;s also true for Leopard, but Leopard&#8217;s <code>NSLog</code> has the additional behavior of sending a message to <code>system.log</code> regardless of whether <code>stderr</code> is redirected. Thus, when you debug or run your app in Xcode (these may amount to the same thing in Xcode 3), messages from <code>NSLog</code> appear both in Xcode&#8217;s console log and in <code>system.log</code>! Curiously, there is no duplication of <code>NSLog</code> messages in <code>system.log</code> when <code>stderr</code> is not redirected.</p>
<p>If you prefer to keep your debug output out of <code>system.log</code>, the workaround for this new <code>NSLog</code> behavior is to abandon <code>NSLog</code> for debugging purposes on Leopard. <img src='http://lapcatsoftware.com/blog/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />   After much experimentation with <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/asl.3.html" title="asl(3)"><code>asl</code></a>, I realized that our old faithful <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/printf.3.html" title="printf(3)"><code>printf</code></a> would work. Since <code>printf</code> writes to <code>stdout</code>, its output is redirected by Xcode. Plus, when you&#8217;re debugging your app in Xcode you don&#8217;t really need <code>NSLog</code> to tell you the name of your app, the date, or your shoe size.</p>
<p>A limitation of <code>printf</code> is that it doesn&#8217;t handle the <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html" title="String Format Specifiers">format specifier</a> <code>%@</code> for an Objective-C object. With Cocoa, therefore, we want an Objective-C wrapper around <code>printf</code> (like, um, <code>NSLog</code>). If you add the following code to your target&#8217;s <code>.pch</code> file, you&#8217;ll have an Objective-C debug logging function <code>JJLog</code> available throughout your target&#8217;s code. To enable logging in your app&#8217;s debug build, just add <code>JJLOGGING</code> to the <code>GCC_PREPROCESSOR_DEFINITIONS</code> setting (AKA &#8220;Preprocessor Macros&#8221;) in the debug build configuration.</p>
<pre><code>
#ifdef __OBJC__
	#import &lt;Cocoa/Cocoa.h&gt;
	#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
</code></pre>
<p>In your app&#8217;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 <code>GCC_PRECOMPILE_PREFIX_HEADER</code>, because Xcode already generates a separate precompiled prefix header for each build configuration. See the <code>.pch.gch.hash-criteria</code> files in <code>/Library/Caches/com.apple.Xcode.###/SharedPrecompiledHeaders</code>.</p>
<p>You can send gobs of gab to <code>JJLog</code> without repercussion or remorse. However, you&#8217;ll still want to use <code>NSLog</code> (sparingly, please) for runtime errors in your release build. Now to continue in the spirit of this post, I&#8217;ll redirect the epilogue to <code>/dev/null</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/01/06/logging-in-leopard/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Embedding frameworks in loadable bundles</title>
		<link>http://lapcatsoftware.com/blog/2007/08/11/embedding-frameworks-in-loadable-bundles/</link>
		<comments>http://lapcatsoftware.com/blog/2007/08/11/embedding-frameworks-in-loadable-bundles/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 15:37:54 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/2007/08/11/embedding-frameworks-in-loadable-bundles/</guid>
		<description><![CDATA[While I worked for Marko Karrpinen &#38; Co. I only made one commit to BaseTen, but as Sappho would say, that one was a doozie! BaseTen is an open source Cocoa framework for PostgreSQL. It has an API resembling Apple&#8217;s Core Data framework, which uses SQLite. You can check out the source and build BaseTen.framework [...]]]></description>
			<content:encoded><![CDATA[<p>While I worked for <a href="http://www.karppinen.fi/" title="MK&amp;C">Marko Karrpinen &amp; Co.</a> I only made one commit to <a href="http://www.karppinen.fi/baseten/" title="BaseTen">BaseTen</a>, but as Sappho would say, that one was a doozie! BaseTen is an open source Cocoa framework for <a href="http://www.postgresql.org/" title="PostgreSQL">PostgreSQL</a>. It has an API resembling Apple&#8217;s <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html" title="Core Data Programming Guide">Core Data</a> framework, which uses <a href="http://www.sqlite.org/" title="SQLite">SQLite</a>. You can check out the source and build <code>BaseTen.framework</code> as well as the optional <code>BaseTenAppKit.framework</code> and an Interface Builder palette, <code>BaseTenPalette.palette</code>. (By the way, I abhor Interface Builder. Or at least Interface Builder 2. I&#8217;ll reserve judgment on Interface Builder 3 until I learn more about it, and only then will I abhor it.) The frameworks are designed to be embedded within your application&#8217;s bundle, in the standard location for embedded frameworks: the directory <code>Contents/Frameworks</code>.</p>
<p>An app needs to know how to locate linked frameworks at runtime, so at compile time the app&#8217;s executable gets a record of each linked framework&#8217;s <em>install name</em>. An install name is, as you should expect by now, not a name. It&#8217;s a path, namely, the location of the dynamic library containing the framework&#8217;s code. To be exact, the install name is where the library <em>should be</em> at runtime, for a library wouldn&#8217;t even need an install name if it just indicated where the library <em>actually is</em> at compile time. Install names enable you to target Panther, for example, while still compiling with Tiger. You can use the command-line <code>otool -D</code> to see that the install name of</p>
<pre><code>/Developer/SDKs/MacOSX10.3.9.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation</code></pre>
<p>is</p>
<pre><code>/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation</code></pre>
</p>
<p>Using absolute paths for install names is fine when your app links against system frameworks, which reside in pre-determined locations, but absolute paths won&#8217;t suffice when your app links against embedded frameworks, because the app could be installed almost anywhere in the file hierarchy, e.g., <code>~/Desktop</code> or <code>/Volumes/MyDistributionDmg</code>. That&#8217;s why an embedded framework needs a relative path install name. The BaseTen and BaseTenAppKit projects achieve this by setting the build setting <code>INSTALL_PATH</code> (what else would you do with a build setting but set it?) to <code>@executable_path/../Frameworks</code>. The relative <code>@executable_path</code> is the path to the <code>Contents/MacOS</code> directory in your application&#8217;s bundle. When BaseTen is built with that build setting (to answer my last question, you would build with it), the install name of the framework becomes</p>
<pre><code>@executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen</code></pre>
<p>as you can verify with <code>otool -D</code>. Thus, when your app links against <code>BaseTen.framework</code> and records the install name, it can find the framework in its own bundle at runtime.</p>
<p>BaseTen&#8217;s IB palette needs to use the BaseTen frameworks too. The problem, however, is that if the frameworks are built to be embedded in an application, they aren&#8217;t configured correctly to be embedded in the palette. When Interface Builder launches it will fail to load the palette, logging an error:</p>
<pre>Interface Builder[29996] *** -[NSBundle load]: Error loading code /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette for bundle /Users/jeff/Library/Palettes/BaseTenPalette.palette, error code 4 (link edit error code 4, error number 0 (Library not loaded: @executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen
  Referenced from: /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette
  Reason: image not found))</pre>
</p>
<p>The reason that the image is not found &mdash; the reason behind the reason &mdash; is that the executable in this case in not actually BaseTenPalette but rather Interface Builder itself, which is trying to load the palette. The <code>@executable_path</code> leads to</p>
<pre><code>/Developer/Applications/Interface Builder.app/Contents/MacOS</code></pre>
<p>but BaseTen is embedded in</p>
<pre><code>~/Library/Palettes/BaseTenPalette.palette/Contents/Frameworks</code></pre>
<p>so the install name doesn&#8217;t locate the framework at runtime.</p>
<p>In <a href="http://developer.apple.com/releasenotes/DeveloperTools/RN-dyld/index.html" title="dyld Release Notes for Mac OS X v10.4">Tiger</a>, the relative <code>@loader_path</code> was introduced to supplement <code>@executable_path</code>. The <code>@loader_path</code> is relative to the image loading the dynamic library, wherever that image may be. Thus, if we change the install name of BaseTen to</p>
<pre><code>@loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen</code></pre>
<p>and the install name of BaseTenAppKit to</p>
<pre><code>@loader_path/../Frameworks/BaseTenAppKit.framework/Versions/A/BaseTenAppKit</code></pre>
<p>then BaseTenPalette should be able to locate the frameworks when Interface Builder launches. Problem solved, right?</p>
<p>If you&#8217;ve already skipped ahead to the end of this post, you&#8217;ll know that the problem is not solved. (Spoiler alert: Harry drops out of school to follow Trey Anastasio.) We&#8217;ve eliminated one error only to find another:</p>
<pre>Interface Builder[2599] *** -[NSBundle load]: Error loading code /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/BaseTenPalette for bundle /Users/jeff/Library/Palettes/BaseTenPalette.palette, error code 4 (link edit error code 4, error number 0 (Library not loaded: @loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen
  Referenced from: /Users/jeff/Library/Palettes/BaseTenPalette.palette/Contents/MacOS/../Frameworks/BaseTenAppKit.framework/Versions/A/BaseTenAppKit
  Reason: image not found))</pre>
<p>Whereas BaseTenPalette can now find BaseTen at runtime, BaseTenAppKit cannot. They both have a record of BaseTen&#8217;s install name as</p>
<pre><code>@loader_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen</code></pre>
<p>but they don&#8217;t have the same <code>@loader_path</code>.</p>
<p>At this point, you may throw up your hands and throw in the towel, exclaiming <q>Alas, BaseTen cannot have two install names!</q> &mdash; or some such exclamation perhaps not suitable for children. (<q>Oh rat farts!</q>). Yet your exclamation would be in vain, because the install name of the dynamic library doesn&#8217;t matter after linking. All that matters is the install name recorded in the linked executable, and that can be forged.</p>
<p>Apple provides the nefarious command-line <code>install_name_tool</code> to forge install names for dylibs and give them fake id&#8217;s. This is how frameworks get into bars, since there are very few that are twenty-one years old. You can examine the details of my fix in the <a href="http://www.karppinen.fi/baseten/changeset/112" title="Changeset 112">BaseTen Trac</a>, but basically what I did to allow BaseTenAppKit to find BaseTen was to run the following command in a build phase script for BaseTenPalette:</p>
<pre><code>
install_name_tool -change \
	"@executable_path/../Frameworks/BaseTen.framework/Versions/A/BaseTen" \
	"@loader_path/../../../../Frameworks/BaseTen.framework/Versions/A/BaseTen" \
	"$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH/BaseTenAppKit.framework/Versions/A/BaseTenAppKit"</code>
	</pre>
</p>
<p>I discovered the correct install name through a stroke a genius, or to put it another way, trial and error. The <code>@loader_path</code> for BaseTenAppKit turns out to be</p>
<pre><code>~/Library/Palettes/BaseTenPalette.palette/Contents/Frameworks/BaseTenAppKit.framework/Versions/A</code></pre>
<p>which makes sense in retrospect, but if you could guess <code>../../../..</code> on your first try, you&#8217;re a superfreak. Anyway, you can check the install names before and after with <code>otool -l</code>, or succinctly with <code>otool -L</code>.</p>
<p><em>Caveat developtor:</em> for <code>install_name_tool</code> to work, you may need to build your frameworks with the option <code>-header-pad_max_install_names</code>. BaseTen already does this. See the man pages for more information, man.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2007/08/11/embedding-frameworks-in-loadable-bundles/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Working without a nib, Part 5: Open Recent menu</title>
		<link>http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/</link>
		<comments>http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 15:38:11 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/</guid>
		<description><![CDATA[Judging from the search phrases in my referrer log and from posts to Apple&#8217;s mailing lists, quite a few people are interested in developing Cocoa applications without using nibs. I&#8217;ve heard the demand, and you&#8217;ll be pleased to learn that the wait is over. I have a sweet solution. Today I&#8217;m announcing a Cocoa nibless [...]]]></description>
			<content:encoded><![CDATA[<p>Judging from the search phrases in my referrer log and from posts to <a href="http://lists.apple.com/" title="Apple Mailing Lists">Apple&#8217;s mailing lists</a>, quite a few people are interested in developing Cocoa applications without using nibs. I&#8217;ve heard the demand, and you&#8217;ll be pleased to learn that the wait is over. I have a sweet solution. Today I&#8217;m announcing a Cocoa nibless SDK. You can download the SDK immediately &mdash; from the web! Specifically, from my blog. Just load this web page in Safari and select <b>Save As&hellip;</b> from the <b>File</b> menu.</p>
<p>(Don&#8217;t worry about me. I hear that the Chairman of the Board has a sense of humor. I&#8217;m sure that these two large gentlemen at my door are here to convey his appreciation of my wit and to deliver an invitation to lunch.)</p>
<p>(No! No! Stop, please! Not the iPod too! Have mercy!)</p>
<p>At the end of <a href="http://lapcatsoftware.com/blog/2007/06/17/working-without-a-nib-part-4-setapplemenu/" title="Working without a nib, Part 4: setAppleMenu">Part 4 of this series</a>, I suggested that we needed to call <code>setValue:@"NSRecentDocumentsMenu" forKey:@"name"</code> to set the <b>Open Recent</b> menu. This is why they call me &#8220;Good Ol&#8217; Oftenwrong&#8221;. Luckily, if you have a document-based application, Cocoa will generously create an <b>Open Recent</b> menu for you. All you need to do is put a menu item with the action <code>@selector(openDocument:)</code> in pretty much any menu, and <b>Open Recent</b> will magically appear as the next item in the menu. Now that&#8217;s a sweet solution! </p>
<p>If you want an <b>Open Recent</b> menu for a non-document app, on the other hand, you need to use an ugly hack. Although it was clear that the <code>NSMenu</code> ivar <code>_name</code> is set to <code>@"NSRecentDocumentsMenu"</code> for the <b>Open Recent</b> menu in a standard Cocoa <code>MainMenu.nib</code>, I couldn&#8217;t get the menu to populate with recent items in my nibless app even after setting <code>_name</code>. By pure trial and error, I discovered that you have to call <code>_setMenuName:@"NSRecentDocumentsMenu"</code> rather than <code>setValue:@"NSRecentDocumentsMenu" forKey:@"name"</code>. (It was a natural choice after trying <code>setName:</code> and <code>_setName:</code>, which are not implemented by <code>NSMenu</code>.) The method <code>_setMenuName:</code> does set the <code>_name</code> ivar, but apparently it does some other crucial stuff too. Perhaps it asks a favor of the iGodfather. Anyway, I&#8217;ve updated my <a href="http://lapcatsoftware.com/downloads/Nibless.zip" title="Nibless.zip">Nibless Xcode project</a> to demonstrate this behavior.</p>
<p>In summary, we have succeeded (by we I mean the royal we) in creating a Cocoa application with a full main menu but without any nib (and without any error messages). For this purpose we&#8217;ve had to call two private methods, <code>-[NSApplication setAppleMenu:]</code> and <code>-[NSMenu _setMenuName:]</code>, as well as <code>poseAsClass:</code> to override <code>+[NSBundle loadNibNamed:owner:]</code>. Not bad. And it&#8217;s taken us less than two months to reproduce what Interface Builder can do in less than two seconds. Isn&#8217;t this fun? The hardest part is finished, though. From now on, it&#8217;s just smooth sailing, on the Good Ship of Pyaray.</p>
<p>Oh, one more thing. Let&#8217;s dance! Anyway you want it.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Working without a nib, Part 5: No, 3!</title>
		<link>http://lapcatsoftware.com/blog/2007/06/10/working-without-a-nib-part-5-no-3/</link>
		<comments>http://lapcatsoftware.com/blog/2007/06/10/working-without-a-nib-part-5-no-3/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 15:38:42 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/2007/06/10/working-without-a-nib-part-5-no-3/</guid>
		<description><![CDATA[For all you desperate souls waiting in line at the Moscone Center, and you more desperate souls waiting in line at MacRumors, take heart, because there&#8217;s something even more desperate than you &#8212; NSApplicationMain(). It&#8217;s so desperate to load a nib that it&#8217;ll take the first one it can find. When your application launches, NSApplicationMain() [...]]]></description>
			<content:encoded><![CDATA[<p id="this-very-post">For all you desperate souls waiting in line at the Moscone Center, and you more desperate souls waiting in line at <a href="http://www.macrumors.com" title="MacRumors">MacRumors</a>, take heart, because there&#8217;s something even more desperate than you &mdash; <code>NSApplicationMain()</code>. It&#8217;s so desperate to load a nib that it&#8217;ll take the first one it can find. When your application launches, <code>NSApplicationMain()</code> instantiates the <code>NSPrincipalClass</code> from your app&#8217;s <code>Info.plist</code> and calls <code>+[NSBundle loadNibNamed:owner:]</code> with the instance as the owner. This method in turn calls <code>+[NSBundle bundleForClass:]</code> with your <code>NSPrincipalClass</code> and <code>-[NSBundle pathForResource:ofType:]</code> with type <code>@"nib"</code>. If your <code>Info.plist</code> contains no <code>NSMainNibFile</code> key, then the nib name and path arguments for those methods are <code>nil</code>. Why in the world would your <code>Info.plist</code> be missing <code>NSMainNibFile</code>? See <a href="http://lapcatsoftware.com/blog/2007/05/16/working-without-a-nib-part-1/" title="Working without a nib, Part 1">Part 1</a> of this series. If that doesn&#8217;t answer the question, see <a href="http://lapcatsoftware.com/blog/2007/06/04/working-without-a-nib-part-2-also-also-wik/" title="Working without a nib, Part 2: Also Also Wik">Part 2</a>. If that doesn&#8217;t answer the question, see <a href="#this-very-post" title="Working without a nib, Part 5: No, 3!">Part 3</a>.</p>
<p>When I set the <code>NSPrincipalClass</code> key to my custom <code>NSApplication</code> subclass, the corresponding bundle for that class is my app&#8217;s main bundle, so if there&#8217;s no nib in the bundle, the app fails to launch with the error, <q>No NSMainNibFile specified in info dictionary, exiting</q>. However, when I leave <code>NSPrincipalClass</code> as <code>NSApplication</code>, the corresponding bundle turns out to be <code>/System/Library/Frameworks/AppKit.framework</code>. If you send the message <code>-[NSBundle pathForResource:nil ofType:@"nib"]</code> to that bundle, it returns <code>/System/Library/Frameworks/AppKit.framework/Resources/English.lproj/NSAlertPanel.nib</code>, which is the first nib file in the <code>English.lproj</code> folder. As a consequence, <code>NSApplicationMain()</code> attempts to load <code>NSAlertPanel.nib</code> and set the file&#8217;s owner to your app&#8217;s <code>NSApplication</code> instance. That particular nib file contains several buttons with the action <code>buttonPressed:</code> targeted at the file&#8217;s owner, but unlike <code>NSAlert</code>, which is specified as the class of the file&#8217;s owner in the nib, <code>NSApplication</code> doesn&#8217;t implement <code>buttonPressed:</code>, so you get the error, <q>Could not connect the action buttonPressed: to target of class NSApplication</q>. Mystery solved! And I would have gotten away with it too, if it wasn&#8217;t for those meddling kids!</p>
<p>There are a number of ways to handle this problem. My preferred workaround, which I&#8217;ve implemented in the revised version of the <a href="http://lapcatsoftware.com/downloads/Nibless.zip" title="Nibless.zip">Nibless</a> project, is to set <code>NSPrincipalClass</code> to <code>JJApplication</code>, call <code>[[JJBundle class] poseAsClass:[NSBundle class]]</code> in <code>main.m</code>, and override an <code>NSBundle</code> method in <code>JJBundle.m</code>:</p>
<pre><code>
+(BOOL) loadNibNamed:(NSString *)aNibNamed owner:(id)owner {
    if (!aNibNamed &amp;&amp; owner == NSApp) {
        // We're lying here. Don't load anything.
        return YES;
    } else {
        return [super loadNibNamed:aNibNamed owner:owner];
    }
}</code></pre>
<p>We now return to our regularly scheduled WWDC speculation. (I predict that everyone in the audience will get a car.) If you are attending The Keynote on Monday, remember to bring plenty of Scooby snacks. If you&#8217;re playing the home game: every time Steve says &#8220;cool&#8221;, drink!</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2007/06/10/working-without-a-nib-part-5-no-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Working without a nib, Part 2: Also Also Wik</title>
		<link>http://lapcatsoftware.com/blog/2007/06/04/working-without-a-nib-part-2-also-also-wik/</link>
		<comments>http://lapcatsoftware.com/blog/2007/06/04/working-without-a-nib-part-2-also-also-wik/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 15:38:59 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/2007/06/04/working-without-a-nib-part-2-also-also-wik/</guid>
		<description><![CDATA[I apologize for the fault in the subtitle. Those responsible have been sacked. What I intended to say was that I&#8217;ve discovered the Holy Grail of Cocoa hacks: how to create a functional Cocoa application without any nib. In Part 1 of this series, I suggested that you needed a nib for the main menu [...]]]></description>
			<content:encoded><![CDATA[<p>I apologize for the fault in the subtitle. Those responsible have been sacked. What I intended to say was that I&#8217;ve discovered the Holy Grail of Cocoa hacks: how to create a functional Cocoa application without any nib. In <a href="http://lapcatsoftware.com/blog/2007/05/16/working-without-a-nib-part-1/" title="Working without a nib, Part 1">Part 1 of this series</a>, I suggested that you needed a nib for the main menu of the app; some would even argue that having a nib is the essence of a Cocoa app. It turns out that I was wrong, and some (they, the unspecified straw persons) were wrong too. I apologize for any faults in my previous post. Those responsible would be sacked, but those responsible for sacking have just been sacked.</p>
<p>As you may recall if you have a photographic memory or nothing better to do, the main problem with getting rid of nibs is setting the application menu. I had been using a minimal nib as a workaround, but now I have a reliable, though undocumented, solution to the problem. I came upon the solution by using <a href="http://developer.apple.com/documentation/DeveloperTools/gdb/gdb/gdb_toc.html" title="Debugging with GDB">gdb</a> and <a href="http://lapcatsoftware.com/blog/2007/03/10/everything-you-always-wanted-to-know-about-nsapplication/" title="Everything you always wanted to know about NSApplication">JJApp</a> (along with a herring) to override <code>initWithCoder:</code> while the main menu is loaded from a nib. The class <code>NSMenu</code> has a private ivar <code>_name</code>, declared in <code>/System/Library/Frameworks/AppKit.framework/Headers/NSMenu.h</code>, that is usually <code>nil</code>, but a few menus &mdash; including the application menu &mdash; have a string value for the ivar. Although there are no public accessors, we can set the value anyway through the magic of <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html#//apple_ref/doc/uid/20000955" title="Accessor Search Implementation Details">key-value coding</a>. For example, I called <code>setValue:@"NSMainMenu" forKey:@"name"</code> on my main menu and <code>setValue:@"NSAppleMenu" forKey:@"name"</code> on my application menu. This must be done before the return of <code>-[NSApplication finishLaunching]</code>, otherwise it will have no effect. I find <code>applicationWillFinishLaunching:</code> to be a good place to set your main menu.</p>
<p>Another caveat is that the old deleting-the-nib trick doesn&#8217;t work at all if you change <code>NSPrincipalClass</code> in <code>Info.plist</code>. When I set it to my <code>NSApplication</code> subclass, the app refuses to launch, complaining, <q>No NSMainNibFile specified in info dictionary, exiting</q>. Strangely, it works fine if I leave <code>NSPrincipalClass</code> alone and call <code>[[JJApplication class] poseAsClass:[NSApplication class]]</code> in <code>main.m</code>. A special treat is that Cocoa automatically adds the <b>Special Characters</b> item to the <b>Edit</b> menu at runtime. Thanks, Cocoa! You can see all of this yourself by downloading my sample Xcode project, <a href="http://lapcatsoftware.com/downloads/Nibless.zip" title="Nibless">Nibless</a>. If you use my code in your app, I may sue you, or I may kiss you. In either case, it&#8217;s a risk you&#8217;ll have to take. (It!)</p>
<p>Despite the fact that my solution is for the most part unsupported by official API (consult the book of armaments!), there&#8217;s good reason to think that it&#8217;s stable and should survive Leopard at least. Apple is unlikely to remove an ivar from such an important class as <code>NSMenu</code>. More important, the value of the ivar seems to be the way that archived menus indicate their function to Cocoa and to Interface Builder, as reflected by the &#8220;Special Menus&#8221; setting in the Inspector. Try opening <code>keyedobjects.nib</code> with <a href="http://www.barebones.com/products/bbedit/" title="Bare Bones Software">BBEdit</a>, and you&#8217;ll see that the file is just a plist containing definitions of the objects in the nib.</p>
<p>In Part 5 of this series &mdash; sorry, Part 3 &mdash; I&#8217;ll investigate the cause of the log message <q>Could not connect the action buttonPressed: to target of class NSApplication</q> when launching without a nib. I&#8217;ll also attempt to populate the <b>Open Recent</b> menu. The <b>Clear Menu</b> item seems to work, but for some reason I can&#8217;t get items to appear in the menu. So, um, anything that you could do to help would be very helpful.</p>
<p>I&#8217;d like to end this post on a personal note. Many of my legions of fans have sent emails asking for more information about me: birth date, hobbies, pet peeves, dress size, etc. I prefer not to start a cult of personality, but I&#8217;ve decided that you, the heroes, deserve something. Thus, I&#8217;m going to share one particularly juicy tidbit. My favorite color is &hellip; blue. No, yellooooooooow!</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2007/06/04/working-without-a-nib-part-2-also-also-wik/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
