diff options
Diffstat (limited to 'nptl/tst-pthread-getattr.c')
-rw-r--r-- | nptl/tst-pthread-getattr.c | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c deleted file mode 100644 index 86719f97ab..0000000000 --- a/nptl/tst-pthread-getattr.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Make sure that the stackaddr returned by pthread_getattr_np is - reachable. - - Copyright (C) 2012-2017 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; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <stdio.h> -#include <string.h> -#include <sys/resource.h> -#include <sys/param.h> -#include <pthread.h> -#include <alloca.h> -#include <assert.h> -#include <unistd.h> -#include <inttypes.h> - -/* There is an obscure bug in the kernel due to which RLIMIT_STACK is sometimes - returned as unlimited when it is not, which may cause this test to fail. - There is also the other case where RLIMIT_STACK is intentionally set as - unlimited or very high, which may result in a vma that is too large and again - results in a test case failure. To avoid these problems, we cap the stack - size to one less than 8M. See the following mailing list threads for more - information about this problem: - <http://sourceware.org/ml/libc-alpha/2012-06/msg00599.html> - <http://sourceware.org/ml/libc-alpha/2012-06/msg00713.html>. */ -#define MAX_STACK_SIZE (8192 * 1024 - 1) - -static size_t pagesize; - -/* Check if the page in which TARGET lies is accessible. This will segfault - if it fails. */ -static volatile char * -allocate_and_test (char *target) -{ - volatile char *mem = (char *) &mem; - /* FIXME: mem >= target for _STACK_GROWSUP. */ - mem = alloca ((size_t) (mem - target)); - - *mem = 42; - return mem; -} - -static int -get_self_pthread_attr (const char *id, void **stackaddr, size_t *stacksize) -{ - pthread_attr_t attr; - int ret; - pthread_t me = pthread_self (); - - if ((ret = pthread_getattr_np (me, &attr)) < 0) - { - printf ("%s: pthread_getattr_np failed: %s\n", id, strerror (ret)); - return 1; - } - - if ((ret = pthread_attr_getstack (&attr, stackaddr, stacksize)) < 0) - { - printf ("%s: pthread_attr_getstack returned error: %s\n", id, - strerror (ret)); - return 1; - } - - return 0; -} - -/* Verify that the stack size returned by pthread_getattr_np is usable when - the returned value is subject to rlimit. */ -static int -check_stack_top (void) -{ - struct rlimit stack_limit; - void *stackaddr; - volatile void *mem; - size_t stacksize = 0; - int ret; - uintptr_t pagemask = ~(pagesize - 1); - - puts ("Verifying that stack top is accessible"); - - ret = getrlimit (RLIMIT_STACK, &stack_limit); - if (ret) - { - perror ("getrlimit failed"); - return 1; - } - - printf ("current rlimit_stack is %zu\n", (size_t) stack_limit.rlim_cur); - - if (get_self_pthread_attr ("check_stack_top", &stackaddr, &stacksize)) - return 1; - - /* Reduce the rlimit to a page less that what is currently being returned - (subject to a maximum of MAX_STACK_SIZE) so that we ensure that - pthread_getattr_np uses rlimit. The figure is intentionally unaligned so - to verify that pthread_getattr_np returns an aligned stacksize that - correctly fits into the rlimit. We don't bother about the case where the - stack is limited by the vma below it and not by the rlimit because the - stacksize returned in that case is computed from the end of that vma and is - hence safe. */ - stack_limit.rlim_cur = MIN (stacksize - pagesize + 1, MAX_STACK_SIZE); - printf ("Adjusting RLIMIT_STACK to %zu\n", (size_t) stack_limit.rlim_cur); - if ((ret = setrlimit (RLIMIT_STACK, &stack_limit)) < 0) - { - perror ("setrlimit failed"); - return 1; - } - - if (get_self_pthread_attr ("check_stack_top2", &stackaddr, &stacksize)) - return 1; - - printf ("Adjusted rlimit: stacksize=%zu, stackaddr=%p\n", stacksize, - stackaddr); - - /* A lot of targets tend to write stuff on top of the user stack during - context switches, so we cannot possibly safely go up to the very top of - stack and test access there. It is however sufficient to simply check if - the top page is accessible, so we target our access halfway up the top - page. Thanks Chris Metcalf for this idea. */ - mem = allocate_and_test (stackaddr + pagesize / 2); - - /* Before we celebrate, make sure we actually did test the same page. */ - if (((uintptr_t) stackaddr & pagemask) != ((uintptr_t) mem & pagemask)) - { - printf ("We successfully wrote into the wrong page.\n" - "Expected %#" PRIxPTR ", but got %#" PRIxPTR "\n", - (uintptr_t) stackaddr & pagemask, (uintptr_t) mem & pagemask); - - return 1; - } - - puts ("Stack top tests done"); - - return 0; -} - -/* TODO: Similar check for thread stacks once the thread stack sizes are - fixed. */ -static int -do_test (void) -{ - pagesize = sysconf (_SC_PAGESIZE); - return check_stack_top (); -} - - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" |