[compiler-rt] r283299 - [sanitizers] Update sanitizers test to better match glibc internals

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 5 00:13:42 PDT 2016


Author: rovka
Date: Wed Oct  5 02:13:42 2016
New Revision: 283299

URL: http://llvm.org/viewvc/llvm-project?rev=283299&view=rev
Log:
[sanitizers] Update sanitizers test to better match glibc internals

Reapply 282061.

One of the tests relying on sem_t's layout gets the wrong value for versions of
glibc newer than 2.21 on platforms that don't have 64-bit atomics (e.g. ARM).

This commit fixes the test to work with:
* versions of glibc >= 2.21 on platforms with 64-bit atomics: unchanged
* versions of glibc >= 2.21 on platforms without 64-bit atomics: the semaphore
value is shifted by SEM_VALUE_SHIFT (which is set to 1 in glibc's internal
headers)
* versions of glibc < 2.21: unchanged

The logic is complicated a bit by the fact that the sanitizers always pick the
oldest version of the symbol available in glibc, which creates discrepancies
between old platforms which contain several versions od the sem_init symbol, and
newer platforms which contain only one.

See the glibc 2.23 sources:
* sysdeps/nptl/internaltypes.h (struct new_sem for glibc >= 2.21 and
                                struct old_sem for glibc < 2.21)
* nptl/sem_getvalue.c

This was uncovered on one of the new buildbots that we are trying to move to
production.

Differential Revision: https://reviews.llvm.org/D24766

Modified:
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc

Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc?rev=283299&r1=283298&r2=283299&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc Wed Oct  5 02:13:42 2016
@@ -17,6 +17,21 @@ typedef uint64_t semval_t;
 typedef unsigned semval_t;
 #endif
 
+// glibc 2.21 has introduced some changes in the way the semaphore value is
+// handled for 32-bit platforms, but since these changes are not ABI-breaking
+// they are not versioned. On newer platforms such as ARM, there is only one
+// version of the symbol, so it's enough to check the glibc version. However,
+// for old platforms such as i386, glibc contains two or even three versions of
+// the sem_init symbol, and the sanitizers always pick the oldest one.
+// Therefore, it is not enough to rely on the __GLIBC_PREREQ macro - we should
+// instead check the platform as well to make sure we only expect the new
+// behavior on platforms where the older symbols do not exist.
+#if defined(__arm__) && __GLIBC_PREREQ(2, 21)
+#define GET_SEM_VALUE(V) ((V) >> 1)
+#else
+#define GET_SEM_VALUE(V) (V)
+#endif
+
 void my_sem_init(bool priv, int value, semval_t *a, unsigned char *b) {
   sem_t sem;
   memset(&sem, 0xAB, sizeof(sem));
@@ -34,10 +49,10 @@ int main() {
   unsigned char b;
 
   my_sem_init(false, 42, &a, &b);
-  assert(a == 42);
+  assert(GET_SEM_VALUE(a) == 42);
   assert(b != 0xAB);
 
   my_sem_init(true, 43, &a, &b);
-  assert(a == 43);
+  assert(GET_SEM_VALUE(a) == 43);
   assert(b != 0xAB);
 }




More information about the llvm-commits mailing list