diff mbox

Avoid expected failure of tst-malloc-thread-fail on ppc

Message ID 5699034B.5080206@redhat.com
State New
Headers show

Commit Message

Florian Weimer Jan. 15, 2016, 2:33 p.m. UTC
ppc has a conformance issue where malloc does not return pointers with
sufficient alignment (bug 6527).  The alignment checks in
tst-malloc-thread-fail reveal this.

I believe a previous attempt to fix this has been rolled back because it
broke undump support in Emacs, so I'm working around this in the test
case.  Getting MALLOC_ALIGNMENT out of malloc.c is a bit tricky because
its definition changes between SHARED and !SHARED, so I created a new
internal header and included it from a dedicated file.

In the future, I will add additional items to <malloc-private.h> for
some whitebox testing.

Tested on powerpc-redhat-linux-gnu and x86_64-redhat-linux-gnu.

Florian

Comments

Florian Weimer May 9, 2016, 11:52 a.m. UTC | #1
On 01/15/2016 03:33 PM, Florian Weimer wrote:
> 2016-01-15  Florian Weimer<fweimer@redhat.com>
>
> 	* malloc/malloc-private.h: New file.
> 	(INTERNAL_SIZE_T, SIZE_SZ, MALLOC_ALIGNMENT, MALLOC_ALIGN_MASK): Moved ...
> 	* malloc/malloc.c (INTERNAL_SIZE_T, SIZE_SZ, MALLOC_ALIGNMENT)
> 	(MALLOC_ALIGN_MASK): ... from here.
> 	* malloc/tst-malloc-thread-fail.c (allocate_1): Use
> 	malloc_alignment.
> 	* malloc/test-malloc-alignment.c, malloc/test-malloc-alignment.h:
> 	New file.
> 	* malloc/Makefile (tst-malloc-thread-fail): Add dependency.

We have a proper fix for bug 6527, so this is no longer necessary.

Florian
diff mbox

Patch

2016-01-15  Florian Weimer  <fweimer@redhat.com>

	* malloc/malloc-private.h: New file.
	(INTERNAL_SIZE_T, SIZE_SZ, MALLOC_ALIGNMENT, MALLOC_ALIGN_MASK): Moved ...
	* malloc/malloc.c (INTERNAL_SIZE_T, SIZE_SZ, MALLOC_ALIGNMENT)
	(MALLOC_ALIGN_MASK): ... from here.
	* malloc/tst-malloc-thread-fail.c (allocate_1): Use
	malloc_alignment.
	* malloc/test-malloc-alignment.c, malloc/test-malloc-alignment.h:
	New file.
	* malloc/Makefile (tst-malloc-thread-fail): Add dependency.

diff --git a/malloc/Makefile b/malloc/Makefile
index 360288b..cac1b5e 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -167,3 +167,5 @@  $(objpfx)libmemusage.so: $(libdl)
 
 # Extra dependencies
 $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c
+
+$(objpfx)tst-malloc-thread-fail: $(objpfx)test-malloc-alignment.o
diff --git a/malloc/malloc-private.h b/malloc/malloc-private.h
new file mode 100644
index 0000000..482a406
--- /dev/null
+++ b/malloc/malloc-private.h
@@ -0,0 +1,91 @@ 
+/* Malloc implementation for multiple threads without lock contention.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Wolfram Gloger <wg@malloc.de>
+   and Doug Lea <dl@cs.oswego.edu>, 2001.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef MALLOC_PRIVATE_H
+#define MALLOC_PRIVATE_H
+
+#include <malloc-machine.h>
+#include <malloc-sysdep.h>
+#include <shlib-compat.h>
+#include <stddef.h>
+
+/* INTERNAL_SIZE_T is the word-size used for internal bookkeeping of
+   chunk sizes.
+
+   The default version is the same as size_t.
+
+   While not strictly necessary, it is best to define this as an
+   unsigned type, even if size_t is a signed type. This may avoid some
+   artificial size limitations on some systems.
+
+   On a 64-bit machine, you may be able to reduce malloc overhead by
+   defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' at the
+   expense of not being able to handle more than 2^32 of malloced
+   space. If this limitation is acceptable, you are encouraged to set
+   this unless you are on a platform requiring 16byte alignments. In
+   this case the alignment requirements turn out to negate any
+   potential advantages of decreasing size_t word size.
+
+   Implementors: Beware of the possible combinations of:
+      - INTERNAL_SIZE_T might be signed or unsigned, might be 32 or 64 bits,
+        and might be the same width as int or as long
+      - size_t might have different width and signedness as INTERNAL_SIZE_T
+      - int and long might be 32 or 64 bits, and might be the same width
+   To deal with this, most comparisons and difference computations
+   among INTERNAL_SIZE_Ts should cast them to unsigned long, being
+   aware of the fact that casting an unsigned int to a wider long does
+   not sign-extend. (This also makes checking for negative numbers
+   awkward.) Some of these casts result in harmless compiler warnings
+   on some systems.  */
+#ifndef INTERNAL_SIZE_T
+#define INTERNAL_SIZE_T size_t
+#endif
+
+/* The corresponding word size.  */
+#define SIZE_SZ (sizeof (INTERNAL_SIZE_T))
+
+
+/* MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks.
+
+   It must be a power of two at least 2 * SIZE_SZ, even on machines
+   for which smaller alignments would suffice. It may be defined as
+   larger than this though. Note however that code and data structures
+   are optimized for the case of 8-byte alignment.  */
+#ifndef MALLOC_ALIGNMENT
+# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_16)
+/* This is the correct definition when there is no past ABI to constrain it.
+
+   Among configurations with a past ABI constraint, it differs from
+   2*SIZE_SZ only on powerpc32.  For the time being, changing this is
+   causing more compatibility problems due to malloc_get_state and
+   malloc_set_state than will returning blocks not adequately aligned for
+   long double objects under -mlong-double-128.  */
+
+#  define MALLOC_ALIGNMENT       (2 * SIZE_SZ < __alignof__ (long double)     \
+                                  ? __alignof__ (long double) : 2 * SIZE_SZ)
+# else
+#  define MALLOC_ALIGNMENT       (2 * SIZE_SZ)
+# endif
+#endif
+
+/* The corresponding bit mask value */
+#define MALLOC_ALIGN_MASK      (MALLOC_ALIGNMENT - 1)
+
+#endif /* MALLOC_PRIVATE_H */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index d20d595..1572448 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -216,8 +216,7 @@ 
 #include <stdlib.h>   /* for getenv(), abort() */
 #include <unistd.h>   /* for __libc_enable_secure */
 
-#include <malloc-machine.h>
-#include <malloc-sysdep.h>
+#include <malloc-private.h>
 
 #include <atomic.h>
 #include <_itoa.h>
@@ -303,76 +302,6 @@  __malloc_assert (const char *assertion, const char *file, unsigned int line,
 
 
 /*
-  INTERNAL_SIZE_T is the word-size used for internal bookkeeping
-  of chunk sizes.
-
-  The default version is the same as size_t.
-
-  While not strictly necessary, it is best to define this as an
-  unsigned type, even if size_t is a signed type. This may avoid some
-  artificial size limitations on some systems.
-
-  On a 64-bit machine, you may be able to reduce malloc overhead by
-  defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' at the
-  expense of not being able to handle more than 2^32 of malloced
-  space. If this limitation is acceptable, you are encouraged to set
-  this unless you are on a platform requiring 16byte alignments. In
-  this case the alignment requirements turn out to negate any
-  potential advantages of decreasing size_t word size.
-
-  Implementors: Beware of the possible combinations of:
-     - INTERNAL_SIZE_T might be signed or unsigned, might be 32 or 64 bits,
-       and might be the same width as int or as long
-     - size_t might have different width and signedness as INTERNAL_SIZE_T
-     - int and long might be 32 or 64 bits, and might be the same width
-  To deal with this, most comparisons and difference computations
-  among INTERNAL_SIZE_Ts should cast them to unsigned long, being
-  aware of the fact that casting an unsigned int to a wider long does
-  not sign-extend. (This also makes checking for negative numbers
-  awkward.) Some of these casts result in harmless compiler warnings
-  on some systems.
-*/
-
-#ifndef INTERNAL_SIZE_T
-#define INTERNAL_SIZE_T size_t
-#endif
-
-/* The corresponding word size */
-#define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))
-
-
-/*
-  MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks.
-  It must be a power of two at least 2 * SIZE_SZ, even on machines
-  for which smaller alignments would suffice. It may be defined as
-  larger than this though. Note however that code and data structures
-  are optimized for the case of 8-byte alignment.
-*/
-
-
-#ifndef MALLOC_ALIGNMENT
-# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_16)
-/* This is the correct definition when there is no past ABI to constrain it.
-
-   Among configurations with a past ABI constraint, it differs from
-   2*SIZE_SZ only on powerpc32.  For the time being, changing this is
-   causing more compatibility problems due to malloc_get_state and
-   malloc_set_state than will returning blocks not adequately aligned for
-   long double objects under -mlong-double-128.  */
-
-#  define MALLOC_ALIGNMENT       (2 *SIZE_SZ < __alignof__ (long double)      \
-                                  ? __alignof__ (long double) : 2 *SIZE_SZ)
-# else
-#  define MALLOC_ALIGNMENT       (2 *SIZE_SZ)
-# endif
-#endif
-
-/* The corresponding bit mask value */
-#define MALLOC_ALIGN_MASK      (MALLOC_ALIGNMENT - 1)
-
-
-
-/*
   REALLOC_ZERO_BYTES_FREES should be set if a call to
   realloc with zero bytes should be the same as a call to free.
   This is required by the C standard. Otherwise, since this malloc
diff --git a/malloc/test-malloc-alignment.c b/malloc/test-malloc-alignment.c
new file mode 100644
index 0000000..492d23a
--- /dev/null
+++ b/malloc/test-malloc-alignment.c
@@ -0,0 +1,28 @@ 
+/* Export malloc alignment for use in test cases.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <test-malloc-alignment.h>
+
+/* If we do not define SHARED, SHLIB_COMPAT in the definition of
+   MALLOC_ALIGNMENT will not provide the expected definition.  Because
+   of the need to define SHARED, we put this definition into a
+   separate file.  */
+#define SHARED 1
+#include <malloc-private.h>
+
+size_t malloc_alignment = MALLOC_ALIGNMENT;
diff --git a/malloc/test-malloc-alignment.h b/malloc/test-malloc-alignment.h
new file mode 100644
index 0000000..940709d
--- /dev/null
+++ b/malloc/test-malloc-alignment.h
@@ -0,0 +1,26 @@ 
+/* Export malloc alignment for use in test cases.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef TEST_MALLOC_ALIGNMENT_H
+#define TEST_MALLOC_ALIGNMENT_H
+
+#include <stddef.h>
+
+extern size_t malloc_alignment;
+
+#endif /* TEST_MALLOC_ALIGNMENT_H */
diff --git a/malloc/tst-malloc-thread-fail.c b/malloc/tst-malloc-thread-fail.c
index fc090ef..4968b19 100644
--- a/malloc/tst-malloc-thread-fail.c
+++ b/malloc/tst-malloc-thread-fail.c
@@ -31,6 +31,8 @@ 
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <test-malloc-alignment.h>
+
 /* Wrapper for calloc with an optimization barrier.  */
 static void *
 __attribute__ ((noinline, noclone))
@@ -82,8 +84,10 @@  allocate_1 (void)
   switch (allocation_function)
     {
     case with_malloc:
+      /* Use malloc_alignment instead of _Alignof (max_align_t) so
+         that this test does not fail due to bug 6527.  */
       return (struct allocate_result)
-        {malloc (allocation_size), _Alignof (max_align_t)};
+        {malloc (allocation_size), malloc_alignment};
     case with_realloc:
       {
         void *p = realloc (NULL, 16);
@@ -96,7 +100,7 @@  allocate_1 (void)
             if (q == NULL)
               free (p);
           }
-        return (struct allocate_result) {q, _Alignof (max_align_t)};
+        return (struct allocate_result) {q, malloc_alignment};
       }
     case with_aligned_alloc:
       {
@@ -145,7 +149,7 @@  allocate_1 (void)
                 printf ("error: non-zero byte at offset %zu\n", i);
                 abort ();
               }
-        return (struct allocate_result) {p, _Alignof (max_align_t)};
+        return (struct allocate_result) {p, malloc_alignment};
       }
     }
   abort ();