This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch, siddhesh/getattr, created. glibc-2.16-ports-merge-87-gb3c84b7
- From: siddhesh at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 27 Jul 2012 16:35:04 -0000
- Subject: GNU C Library master sources branch, siddhesh/getattr, created. glibc-2.16-ports-merge-87-gb3c84b7
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, siddhesh/getattr has been created
at b3c84b775dacf293b65b3370d4e302eecacb0d0d (commit)
- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b3c84b775dacf293b65b3370d4e302eecacb0d0d
commit b3c84b775dacf293b65b3370d4e302eecacb0d0d
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri Jul 27 21:58:55 2012 +0530
TMP: Adjust test case to check halfway up the stackaddr instead at the
edge
diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c
index 692bce4..8b6ca1b 100644
--- a/nptl/tst-pthread-getattr.c
+++ b/nptl/tst-pthread-getattr.c
@@ -38,23 +38,17 @@
#define _MIN(l,o) ((l) < (o) ? (l) : (o))
-/* Move the stack pointer so that stackaddr is accessible and then check if it
- really is accessible. This will segfault if it fails. */
+/* Check if the page in which TARGET lies is accessible. This will segfault
+ if it fails. */
static void *
-allocate_and_test (void *stackaddr)
+allocate_and_test (void *target)
{
void *mem = &mem;
- /* FIXME: mem >= stackaddr for _STACK_GROWSUP. */
- mem = alloca ((size_t) (mem - stackaddr));
- assert (mem <= stackaddr);
-
- /* We don't access mem here because the compiler may move the stack pointer
- beyond what we expect, thus making our alloca send the stack pointer
- beyond stackaddr. Using only stackaddr without the assert may make the
- compiler think that this instruction is independent of the above alloca
- and hence reshuffle to do this dereference before the alloca. */
- *(int *)stackaddr = 42;
- return stackaddr;
+ /* FIXME: mem >= target for _STACK_GROWSUP. */
+ mem = alloca ((size_t) (mem - target));
+
+ *(int *)mem = 42;
+ return mem;
}
static int
@@ -86,7 +80,7 @@ static int
check_stack_top (void)
{
struct rlimit stack_limit;
- void *stackaddr;
+ void *stackaddr, *mem;
size_t stacksize = 0;
int ret;
@@ -126,9 +120,22 @@ check_stack_top (void)
printf ("Adjusted rlimit: stacksize=%zu, stackaddr=%p\n", stacksize,
stackaddr);
- /* So that the compiler does not optimize out this call. */
- stackaddr = allocate_and_test (stackaddr);
- assert (*(int *)stackaddr == 42);
+ /* 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 + 2048);
+
+ /* Before we celebrate, make sure we actually did test the same page. */
+ if (((uintptr_t) stackaddr & ~0xfff ) != ((uintptr_t) mem & ~0xfff))
+ {
+ printf ("We successfully wrote into the wrong page. ");
+ printf ("Expected %lx, but got %lx\n", (uintptr_t) stackaddr & ~0xfff,
+ (uintptr_t) mem & ~0xfff);
+
+ return 1;
+ }
puts ("Stack top tests done");
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b240c804c159f525563736f44a7ecbc73da2997e
commit b240c804c159f525563736f44a7ecbc73da2997e
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri Jul 27 14:58:41 2012 +0530
Get the tst-pthread-getattr fix back into my branch for testing
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 2f38bcc..7a69025 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -6,10 +6,6 @@
* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO):
Likewise.
-2012-07-25 Siddhesh Poyarekar <siddhesh@redhat.com>
-
- * tst-pthread-getattr.c: Revert last change.
-
2012-07-20 Siddhesh Poyarekar <siddhesh@redhat.com>
* tst-pthread-getattr.c (MAX_STACK_SIZE): New max cap for stack
diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c
index 6f2cfc6..692bce4 100644
--- a/nptl/tst-pthread-getattr.c
+++ b/nptl/tst-pthread-getattr.c
@@ -23,16 +23,38 @@
#include <sys/resource.h>
#include <pthread.h>
#include <alloca.h>
+#include <assert.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)
+
+#define _MIN(l,o) ((l) < (o) ? (l) : (o))
/* Move the stack pointer so that stackaddr is accessible and then check if it
really is accessible. This will segfault if it fails. */
-static void
+static void *
allocate_and_test (void *stackaddr)
{
void *mem = &mem;
- /* FIXME: The difference will be negative for _STACK_GROWSUP. */
+ /* FIXME: mem >= stackaddr for _STACK_GROWSUP. */
mem = alloca ((size_t) (mem - stackaddr));
- *(int *)(mem) = 0;
+ assert (mem <= stackaddr);
+
+ /* We don't access mem here because the compiler may move the stack pointer
+ beyond what we expect, thus making our alloca send the stack pointer
+ beyond stackaddr. Using only stackaddr without the assert may make the
+ compiler think that this instruction is independent of the above alloca
+ and hence reshuffle to do this dereference before the alloca. */
+ *(int *)stackaddr = 42;
+ return stackaddr;
}
static int
@@ -77,17 +99,20 @@ check_stack_top (void)
return 1;
}
+ printf ("current rlimit_stack is %zu\n", 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 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 = stacksize - 4095;
+ /* 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 - 4095, MAX_STACK_SIZE);
printf ("Adjusting RLIMIT_STACK to %zu\n", stack_limit.rlim_cur);
if ((ret = setrlimit (RLIMIT_STACK, &stack_limit)))
{
@@ -100,7 +125,10 @@ check_stack_top (void)
printf ("Adjusted rlimit: stacksize=%zu, stackaddr=%p\n", stacksize,
stackaddr);
- allocate_and_test (stackaddr);
+
+ /* So that the compiler does not optimize out this call. */
+ stackaddr = allocate_and_test (stackaddr);
+ assert (*(int *)stackaddr == 42);
puts ("Stack top tests done");
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources