diff options
author | Florian Weimer <fweimer@redhat.com> | 2016-08-26 22:40:27 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2016-08-26 23:20:41 +0200 |
commit | ef4f97648dc95849e417dd3e6328165de4c22185 (patch) | |
tree | 8d250b1f15efcb2d718939c8d75d732efa8e70c2 /nptl | |
parent | 21e79af4cf72429f98480fa34912a4ce236b09a0 (diff) | |
download | glibc-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.c | 156 |
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" |