aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2016-08-26 22:40:27 +0200
committerFlorian Weimer <fweimer@redhat.com>2016-08-26 23:20:41 +0200
commitef4f97648dc95849e417dd3e6328165de4c22185 (patch)
tree8d250b1f15efcb2d718939c8d75d732efa8e70c2 /nptl
parent21e79af4cf72429f98480fa34912a4ce236b09a0 (diff)
downloadglibc-ef4f97648dc95849e417dd3e6328165de4c22185.tar
glibc-ef4f97648dc95849e417dd3e6328165de4c22185.tar.gz
glibc-ef4f97648dc95849e417dd3e6328165de4c22185.tar.bz2
glibc-ef4f97648dc95849e417dd3e6328165de4c22185.zip
malloc: Simplify static malloc interposition [BZ #20432]
Existing interposed mallocs do not define the glibc-internal fork callbacks (and they should not), so statically interposed mallocs lead to link failures because the strong reference from fork pulls in glibc's malloc, resulting in multiple definitions of malloc-related symbols.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/tst-tls3-malloc.c156
1 files changed, 3 insertions, 153 deletions
diff --git a/nptl/tst-tls3-malloc.c b/nptl/tst-tls3-malloc.c
index 8a580fa789..719ab28cf0 100644
--- a/nptl/tst-tls3-malloc.c
+++ b/nptl/tst-tls3-malloc.c
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
/* Reuse the test. */
+#define STACK_SIZE_MB 5
#include "tst-tls3.c"
/* Increase the thread stack size to 10 MiB, so that some thread
@@ -26,156 +27,5 @@ static long stack_size_in_mb = 10;
#include <sys/mman.h>
-/* Interpose a minimal malloc implementation. This implementation
- deliberately interposes just a restricted set of symbols, to detect
- if the TLS code bypasses the interposed malloc. */
-
-/* Lock to guard malloc internals. */
-static pthread_mutex_t malloc_lock = PTHREAD_MUTEX_INITIALIZER;
-
-/* Information about an allocation chunk. */
-struct malloc_chunk
-{
- /* Start of the allocation. */
- void *start;
- /* Size of the allocation. */
- size_t size;
-};
-
-enum { malloc_chunk_count = 1000 };
-static struct malloc_chunk chunks[malloc_chunk_count];
-
-/* Lock the malloc lock. */
-static void
-xlock (void)
-{
- int ret = pthread_mutex_lock (&malloc_lock);
- if (ret != 0)
- {
- errno = ret;
- printf ("error: pthread_mutex_lock: %m\n");
- _exit (1);
- }
-}
-
-/* Unlock the malloc lock. */
-static void
-xunlock (void)
-{
- int ret = pthread_mutex_unlock (&malloc_lock);
- if (ret != 0)
- {
- errno = ret;
- printf ("error: pthread_mutex_unlock: %m\n");
- _exit (1);
- }
-}
-
-/* Internal malloc without locking and registration. */
-static void *
-malloc_internal (size_t size)
-{
- void *result = mmap (NULL, size, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- if (result == MAP_FAILED)
- {
- printf ("error: mmap: %m\n");
- _exit (1);
- }
- return result;
-}
-
-void *
-malloc (size_t size)
-{
- if (size == 0)
- size = 1;
- xlock ();
- void *result = malloc_internal (size);
- for (int i = 0; i < malloc_chunk_count; ++i)
- if (chunks[i].start == NULL)
- {
- chunks[i].start = result;
- chunks[i].size = size;
- xunlock ();
- return result;
- }
- xunlock ();
- printf ("error: no place to store chunk pointer\n");
- _exit (1);
-}
-
-void *
-calloc (size_t a, size_t b)
-{
- if (b != 0 && a > SIZE_MAX / b)
- return NULL;
- /* malloc uses mmap, which provides zeroed memory. */
- return malloc (a * b);
-}
-
-static void
-xunmap (void *ptr, size_t size)
-{
- int ret = munmap (ptr, size);
- if (ret < 0)
- {
- printf ("error: munmap (%p, %zu) failed: %m\n", ptr, size);
- _exit (1);
- }
-}
-
-void
-free (void *ptr)
-{
- if (ptr == NULL)
- return;
-
- xlock ();
- for (int i = 0; i < malloc_chunk_count; ++i)
- if (chunks[i].start == ptr)
- {
- xunmap (ptr, chunks[i].size);
- chunks[i] = (struct malloc_chunk) {};
- xunlock ();
- return;
- }
- xunlock ();
- printf ("error: tried to free non-allocated pointer %p\n", ptr);
- _exit (1);
-}
-
-void *
-realloc (void *old, size_t size)
-{
- if (old != NULL)
- {
- xlock ();
- for (int i = 0; i < malloc_chunk_count; ++i)
- if (chunks[i].start == old)
- {
- size_t old_size = chunks[i].size;
- void *result;
- if (old_size < size)
- {
- result = malloc_internal (size);
- /* Reuse the slot for the new allocation. */
- memcpy (result, old, old_size);
- xunmap (old, old_size);
- chunks[i].start = result;
- chunks[i].size = size;
- }
- else
- /* Old size is not smaller, so reuse the old
- allocation. */
- result = old;
- xunlock ();
- return result;
- }
- xunlock ();
- printf ("error: tried to realloc non-allocated pointer %p\n", old);
- _exit (1);
- }
- else
- return malloc (size);
-}
+#define INTERPOSE_THREADS 1
+#include "../malloc/tst-interpose-aux.c"