RegExKitLite v. Clang
July 23rd, 2010I finally updated to Xcode 3.2.3. I was a little late because I had other priorities, but I wanted to get my iPhone projects building and installing onto my iPhone OS 4.0 devices, so I decided to download and install the latest SDK.
Unfortunately, this seemingly minor update presented a major failure in my debug builds, which I’m adventurously compiling using the LLVM clang compiler. They built fine with Xcode 3.2.2, but starting in 3.2.3, I got a linkage failure, tracing back to the popular open source RegExKitLite:
Undefined symbols: "___gxx_personality_v0", referenced from: _rkl_debugCacheSpinLock in RegexKitLite.o ... "__ZSt9terminatev", referenced from: +[NSString(RegexKitLiteAdditions) clearStringCache] in RegexKitLite.o
What? Those symbols smack of C++, but there isn’t any C++ code in my project. At least, I don’t think there is. RegExKitLite is so famously advanced in its designed, I couldn’t easily tell you whether there was stuff in there intended as C++ or not. On a whim, I tried to switch the file type to C++ to see if that made clang any happier. No, it screamed bloody murder. It agrees with me, RegExKitLite is not C++ code.
So why the link errors? I examined the compile line carefully for RegExKitLite and confirmed that it’s using clang in a manner that should only be generating plain C linkage:
/Developer/usr/bin/clang -x objective-c -arch x86_64 ...
But when I look at the resulting RegExKitLite.o with the “nm” command-line tool, it shows the culprits symbols have been listed as references in the binary object file:
% nm RegexKitLite.o | grep -e terminate\\\|personality U __ZSt9terminatev U ___gxx_personality_v0
Normally when I’m getting some kind of issue like this, I just type in the problematic symbols in to Google and usually find somebody else has found and solved the problem. No such luck this time. There are lots of false positives for the typical reason somebody runs into this link error: they are compiling legitimate C++ code but neglecting to link with the stdc++ library. But in our case, we are not compiling C++ code, but we’re ending up with C++ dependencies nonetheless.
I hopped on to the #clang IRC channel on irc.oftc.net, where a couple extremely helpful clang engineers (thanks to dgregor and rjmccall) helped talk me through the problem, and determine that it does seem to be a clang 1.5 bug. They confirmed that with their latest and greatest clang the bug seems to be fixed, but I was curious to confirm it myself, so I checked out and built the latest clang, too. Sure enough, all is well for future generations!
But what do we do now, stuck with the clang 1.5 that ships with Xcode? There is a crude workaround: simply link to stdc++. But yuck! All that C++ linkage dirtying up my pristine Objective-C project? Since I only use clang (for now) to build debug builds, I don’t have too much of a problem doing this. But if I was shipping these binaries I would be very hesitant to make that concession.
Radar #8230225: clang 1.5 forces linkage to C++ for non-C++ source file
(Open Radar Link)
The best we can do is report the issue to Apple and let them decide whether it’s worth their time to backport whatever fix in later clang is missing from clang 1.5. If you have other suggestions for how to work around the problem in the mean time, please do chime in with a comment below.
Update: The author of RegExKitLite kindly chimed in below with a pointer to the revision in the clang source repository that that fixes the issue. He also suggests a simple, and seemingly safe workaround, involving a slight tweak to the RegExKitLite source code.
July 23rd, 2010 at 9:03 pm
It’s a bug in clang: http://llvm.org/viewvc/llvm-project?view=rev&revision=103938
RegexKitLites use of __attribute__((cleanup)) is what tickles the bug. If you want a way around the bug that doesn’t involve linking to libstdc++, you can do this:
Somewhere around line 169 in RegexKitLite.m 4.0, make the following change:
//#define RKL_HAVE_CLEANUP
//#define RKL_CLEANUP(func) RKL_ATTRIBUTES(cleanup(func))
#define RKL_CLEANUP(func)
The __attribute__((cleanup)) stuff is there just as a safety net, it’s not actually needed to make things run correctly. It’s there to catch lock / didn’t unlock bugs only.
July 23rd, 2010 at 9:10 pm
Thanks, John! Sounds like a good workaround, and I’ll apply it.
July 23rd, 2010 at 9:35 pm
Could also try the Xcode4 preview. It installs Clang 2.0, which may not have the bug. Plus, you can still use Xcode 3.
July 24th, 2010 at 6:07 am
I’ve also found that 3.2.3 won’t let me build a release build of some apps. I keep getting duplicate symbol errors from the linker. The solution is to turn off Link Time Optimization for now.
July 24th, 2010 at 7:15 am
Is it really important that you use 3.2.3? It sounds like you would be better off using 3.2.2 until 4.0 is stable enough for production work.
I was actually quite surprised to see them bump Clang from 1.0.2 to 1.5 in a dot-dot release.
July 24th, 2010 at 10:33 am
Could you switch your code to use the built-in regular expression support now that it’s there?
i.e. NSRegularExpression et al
It has support for all the fun stuff, like capture groups.
July 24th, 2010 at 10:53 am
David – that would be a really great solution, but unfortunately NSRegularExpression is only available on iPhone OS, not on Mac OS X.
July 24th, 2010 at 12:11 pm
Something to look forward to in 10.7 then. =)
July 25th, 2010 at 12:44 pm
Clang in Xcode 3.2.3 seems generally buggy. I see incorrect runtime behavior when using Apple’s recommended check for an iOS 4.0 function (symbol != NULL) where even though the symbol is NULL on iOS 3.1.3, the code takes that branch and tries to call it, followed by the expected blow-up. bbum thought it was a linker bug. I filed it and haven’t heard anything since.
July 29th, 2010 at 3:22 am
Thanks for the detailed page and the bugfix..
May 4th, 2011 at 8:13 am
Hi,
I am trying to create a Document-based application in Lion OS. In the .nib file i am using NSBrowser, i set the maximum column as 3 and Autosizing in all the direction. When i run the application i am getting only 2 column after selecting or resizing the window i am able to see all the 3 columns.
Please let me know that it is a Lion OS issue or Xcode issue.
Thanks in Advance,
Arun
May 4th, 2011 at 9:28 am
Hi Arun- this isn’t a great place for programming tech support questions. I would usually recommend Stack Overflow, but since this is a possibly Lion-related question, you should probably raise the issue on Apple’s NDA-protected forums:
https://devforums.apple.com/