folly: disable address sanitizer warnings on fbstring
authorAndrew Gallagher <agallagher@fb.com>
Tue, 3 Sep 2013 07:26:59 +0000 (00:26 -0700)
committerJordan DeLong <jdelong@fb.com>
Sun, 8 Sep 2013 01:51:05 +0000 (18:51 -0700)
Summary:
The fbstring constructor does word-aligned copies which may creep
past the end of the C string, which address sanitizer doesn't like.

This also adds a address-sanitizer-disabling-attribute to both
Portability.h (for general use) and a (gross) copy in FBString.h
since it gets put into libstdc++.

Test Plan: ran address sanitizer on folly tests

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D950586

folly/FBString.h
folly/Portability.h

index cc34fe668491447f71c46b06046236222583bfcb..e00194babfe8d542b4c5e0f1e1bca8150fe99a28 100644 (file)
@@ -112,6 +112,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 namespace folly {
 #endif
 
+// Different versions of gcc/clang support different versions of
+// the address sanitizer attribute.
+#if defined(__clang__)
+# if __has_attribute(__no_address_safety_analysis__)
+#  define FBSTRING_DISABLE_ADDRESS_SANITIZER \
+     __attribute__((__no_address_safety_analysis__))
+# elif __has_attribute(__no_sanitize_address__)
+#  define FBSTRING_DISABLE_ADDRESS_SANITIZER \
+     __attribute__((__no_sanitize_address__))
+# else
+#  define FBSTRING_DISABLE_ADDRESS_SANITIZER
+# endif
+#elif defined (__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
+# define FBSTRING_DISABLE_ADDRESS_SANITIZER \
+    __attribute__((__no_address_safety_analysis__))
+#else
+# define FBSTRING_DISABLE_ADDRESS_SANITIZER
+#endif
+
 namespace fbstring_detail {
 
 template <class InIt, class OutIt>
@@ -347,7 +366,11 @@ public:
     }
   }
 
-  fbstring_core(const Char *const data, const size_t size) {
+  // NOTE(agallagher): The word-aligned copy path copies bytes which are
+  // outside the range of the string, and makes address sanitizer unhappy,
+  // so just disable it on this function.
+  fbstring_core(const Char *const data, const size_t size)
+      FBSTRING_DISABLE_ADDRESS_SANITIZER {
     // Simplest case first: small strings are bitblitted
     if (size <= maxSmallSize) {
       // Layout is: Char* data_, size_t size_, size_t capacity_
@@ -2392,6 +2415,7 @@ struct hash< ::folly::fbstring> {
 
 #endif // _LIBSTDCXX_FBSTRING
 
+#undef FBSTRING_DISABLE_ADDRESS_SANITIZER
 #undef FBSTRING_LIKELY
 #undef FBSTRING_UNLIKELY
 
index 2989ebea10d2b8a62f62dea6784aa96a1f026db8..07852f2d97792825937ab5dceb182030f0642f8b 100644 (file)
@@ -84,4 +84,23 @@ struct MaxAlign { char c; } __attribute__((aligned));
 # endif
 #endif
 
+/* Define attribute wrapper for function attribute used to disable
+ * address sanitizer instrumentation */
+#if defined(__clang__)
+# if __has_attribute(__no_address_safety_analysis__)
+#  define FOLLY_DISABLE_ADDRESS_SANITIZER \
+     __attribute__((__no_address_safety_analysis__))
+# elif __has_attribute(__no_sanitize_address__)
+#  define FOLLY_DISABLE_ADDRESS_SANITIZER \
+     __attribute__((__no_sanitize_address__))
+# else
+#  define FOLLY_DISABLE_ADDRESS_SANITIZER
+# endif
+#elif defined (__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
+# define FOLLY_DISABLE_ADDRESS_SANITIZER \
+    __attribute__((__no_address_safety_analysis__))
+#else
+# define FOLLY_DISABLE_ADDRESS_SANITIZER
+#endif
+
 #endif // FOLLY_PORTABILITY_H_