A portable way to check whether __CFInitialize has been called: compare kCFAllocatorSystemDefault._base._cfisa to 0.
This should fix http://code.google.com/p/address-sanitizer/issues/detail?id=87 on both Lion and Snow Leopard.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@159821 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
index 740c011..b219e0a 100644
--- a/lib/asan/asan_mac.cc
+++ b/lib/asan/asan_mac.cc
@@ -379,28 +379,6 @@
                                             gencountp);
 }
 
-// CF_RC_BITS, the layout of CFRuntimeBase and __CFStrIsConstant are internal
-// and subject to change in further CoreFoundation versions. Apple does not
-// guarantee any binary compatibility from release to release.
-
-// See http://opensource.apple.com/source/CF/CF-635.15/CFInternal.h
-#if defined(__BIG_ENDIAN__)
-#define CF_RC_BITS 0
-#endif
-
-#if defined(__LITTLE_ENDIAN__)
-#define CF_RC_BITS 3
-#endif
-
-// See http://opensource.apple.com/source/CF/CF-635.15/CFRuntime.h
-typedef struct __CFRuntimeBase {
-  uptr _cfisa;
-  u8 _cfinfo[4];
-#if __LP64__
-  u32 _rc;
-#endif
-} CFRuntimeBase;
-
 // See http://opensource.apple.com/source/CF/CF-635.15/CFString.c
 int __CFStrIsConstant(CFStringRef str) {
   CFRuntimeBase *base = (CFRuntimeBase*)str;
diff --git a/lib/asan/asan_mac.h b/lib/asan/asan_mac.h
index 4917b20..e3412bd 100644
--- a/lib/asan/asan_mac.h
+++ b/lib/asan/asan_mac.h
@@ -14,6 +14,28 @@
 #ifndef ASAN_MAC_H
 #define ASAN_MAC_H
 
+// CF_RC_BITS, the layout of CFRuntimeBase and __CFStrIsConstant are internal
+// and subject to change in further CoreFoundation versions. Apple does not
+// guarantee any binary compatibility from release to release.
+
+// See http://opensource.apple.com/source/CF/CF-635.15/CFInternal.h
+#if defined(__BIG_ENDIAN__)
+#define CF_RC_BITS 0
+#endif
+
+#if defined(__LITTLE_ENDIAN__)
+#define CF_RC_BITS 3
+#endif
+
+// See http://opensource.apple.com/source/CF/CF-635.15/CFRuntime.h
+typedef struct __CFRuntimeBase {
+  uptr _cfisa;
+  u8 _cfinfo[4];
+#if __LP64__
+  u32 _rc;
+#endif
+} CFRuntimeBase;
+
 enum {
   MACOS_VERSION_UNKNOWN = 0,
   MACOS_VERSION_LEOPARD,
diff --git a/lib/asan/asan_malloc_mac.cc b/lib/asan/asan_malloc_mac.cc
index 5770324..34591eb 100644
--- a/lib/asan/asan_malloc_mac.cc
+++ b/lib/asan/asan_malloc_mac.cc
@@ -397,13 +397,10 @@
     // If __CFInitialize() hasn't been called yet, cf_asan will be installed
     // as the default allocator after __CFInitialize() finishes (see the
     // interceptor for __CFInitialize() above). Otherwise install cf_asan right
-    // now. On Snow Leopard we can check for __CFRuntimeClassTableSize, but on
-    // Lion it is private, so we can't.
-    if (GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD) {
-      int *cf_rcts = (int*)dlsym(RTLD_SELF, "__CFRuntimeClassTableSize");
-      if (cf_rcts && *cf_rcts) CFAllocatorSetDefault(cf_asan);
-    } else {
-      // FIXME: how can we check __CFInitialize() has been called already?
+    // now. On both Snow Leopard and Lion __CFInitialize() calls
+    // __CFAllocatorInitialize(), which initializes the _base._cfisa field of
+    // the default allocators we check here.
+    if (((CFRuntimeBase*)kCFAllocatorSystemDefault)->_cfisa) {
       CFAllocatorSetDefault(cf_asan);
     }
   }