]>
Commit | Line | Data |
---|---|---|
bb330e25 AF |
1 | diff -pruN glibc-2.12-2-gc4ccff1/csu/libc-start.c glibc-2.12-2-gc4ccff1.fixed/csu/libc-start.c |
2 | --- glibc-2.12-2-gc4ccff1/csu/libc-start.c 2010-05-04 16:57:23.000000000 +0530 | |
3 | +++ glibc-2.12-2-gc4ccff1.fixed/csu/libc-start.c 2013-07-09 23:34:59.596859295 +0530 | |
4 | @@ -33,7 +33,7 @@ extern int __libc_multiple_libcs; | |
5 | #include <tls.h> | |
6 | #ifndef SHARED | |
7 | # include <dl-osinfo.h> | |
8 | -extern void __pthread_initialize_minimal (void); | |
9 | +extern void __pthread_initialize_minimal (int, char **, char **); | |
10 | # ifndef THREAD_SET_STACK_GUARD | |
11 | /* Only exported for architectures that don't store the stack guard canary | |
12 | in thread local area. */ | |
13 | @@ -143,7 +143,7 @@ LIBC_START_MAIN (int (*main) (int, char | |
14 | /* Initialize the thread library at least a bit since the libgcc | |
15 | functions are using thread functions if these are available and | |
16 | we need to setup errno. */ | |
17 | - __pthread_initialize_minimal (); | |
18 | + __pthread_initialize_minimal (argc, argv, __environ); | |
19 | ||
20 | /* Set up the stack checker's canary. */ | |
21 | uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); | |
22 | diff -pruN glibc-2.12-2-gc4ccff1/csu/libc-tls.c glibc-2.12-2-gc4ccff1.fixed/csu/libc-tls.c | |
23 | --- glibc-2.12-2-gc4ccff1/csu/libc-tls.c 2010-05-04 16:57:23.000000000 +0530 | |
24 | +++ glibc-2.12-2-gc4ccff1.fixed/csu/libc-tls.c 2013-07-09 23:34:59.596859295 +0530 | |
25 | @@ -244,7 +244,7 @@ _dl_tls_setup (void) | |
26 | not used. */ | |
27 | void | |
28 | __attribute__ ((weak)) | |
29 | -__pthread_initialize_minimal (void) | |
30 | +__pthread_initialize_minimal (int argc, char **argv, char **envp) | |
31 | { | |
32 | __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN); | |
33 | } | |
34 | diff -pruN glibc-2.12-2-gc4ccff1/nptl/Makefile glibc-2.12-2-gc4ccff1.fixed/nptl/Makefile | |
35 | --- glibc-2.12-2-gc4ccff1/nptl/Makefile 2013-07-09 23:35:21.692858252 +0530 | |
36 | +++ glibc-2.12-2-gc4ccff1.fixed/nptl/Makefile 2013-07-09 23:34:59.597859295 +0530 | |
37 | @@ -197,7 +197,7 @@ CFLAGS-pt-system.c = -fexceptions | |
38 | ||
39 | ||
40 | tests = tst-typesizes \ | |
41 | - tst-attr1 tst-attr2 tst-attr3 \ | |
42 | + tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ | |
43 | tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ | |
44 | tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \ | |
45 | tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \ | |
46 | @@ -279,6 +279,13 @@ LDFLAGS-pthread.so = -Wl,--enable-new-dt | |
47 | LDFLAGS-tst-cond24 = -lrt | |
48 | LDFLAGS-tst-cond25 = -lrt | |
49 | ||
50 | +# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack | |
51 | +# from resizing the input size to avoid the 64K aliasing conflict on Intel | |
52 | +# processors. | |
53 | +DEFAULT_STACKSIZE=1052672 | |
54 | +CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE) | |
55 | +tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE) | |
56 | + | |
57 | include ../Makeconfig | |
58 | ||
59 | ifeq ($(have-forced-unwind),yes) | |
60 | diff -pruN glibc-2.12-2-gc4ccff1/nptl/nptl-init.c glibc-2.12-2-gc4ccff1.fixed/nptl/nptl-init.c | |
61 | --- glibc-2.12-2-gc4ccff1/nptl/nptl-init.c 2013-07-09 23:35:21.723858250 +0530 | |
62 | +++ glibc-2.12-2-gc4ccff1.fixed/nptl/nptl-init.c 2013-07-09 23:36:35.070854789 +0530 | |
63 | @@ -36,6 +36,7 @@ | |
64 | #include <smp.h> | |
65 | #include <lowlevellock.h> | |
66 | #include <kernel-features.h> | |
67 | +#include <libc-internal.h> | |
68 | ||
69 | ||
70 | /* Size and alignment of static TLS block. */ | |
71 | @@ -288,8 +289,28 @@ extern void **__libc_dl_error_tsd (void) | |
72 | /* This can be set by the debugger before initialization is complete. */ | |
73 | static bool __nptl_initial_report_events __attribute_used__; | |
74 | ||
75 | +/* Validate and set the default stacksize. */ | |
76 | +static void | |
77 | +set_default_stacksize (size_t stacksize) | |
78 | +{ | |
79 | + if (stacksize < PTHREAD_STACK_MIN) | |
80 | + stacksize = PTHREAD_STACK_MIN; | |
81 | + | |
82 | + /* Make sure it meets the minimum size that allocate_stack | |
83 | + (allocatestack.c) will demand, which depends on the page size. */ | |
84 | + const uintptr_t pagesz = GLRO(dl_pagesize); | |
85 | + const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK; | |
86 | + | |
87 | + if (stacksize < minstack) | |
88 | + stacksize = minstack; | |
89 | + | |
90 | + /* Round the resource limit up to page size. */ | |
91 | + stacksize = ALIGN_UP (stacksize, pagesz); | |
92 | + __default_pthread_attr.stacksize = stacksize; | |
93 | +} | |
94 | + | |
95 | void | |
96 | -__pthread_initialize_minimal_internal (void) | |
97 | +__pthread_initialize_minimal_internal (int argc, char **argv, char **envp) | |
98 | { | |
99 | #ifndef SHARED | |
100 | /* Unlike in the dynamically linked case the dynamic linker has not | |
101 | @@ -413,29 +434,44 @@ __pthread_initialize_minimal_internal (v | |
102 | ||
103 | __static_tls_size = roundup (__static_tls_size, static_tls_align); | |
104 | ||
105 | - /* Determine the default allowed stack size. This is the size used | |
106 | - in case the user does not specify one. */ | |
107 | - struct rlimit limit; | |
108 | - if (getrlimit (RLIMIT_STACK, &limit) != 0 | |
109 | - || limit.rlim_cur == RLIM_INFINITY) | |
110 | - /* The system limit is not usable. Use an architecture-specific | |
111 | - default. */ | |
112 | - limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE; | |
113 | - else if (limit.rlim_cur < PTHREAD_STACK_MIN) | |
114 | - /* The system limit is unusably small. | |
115 | - Use the minimal size acceptable. */ | |
116 | - limit.rlim_cur = PTHREAD_STACK_MIN; | |
117 | + /* Initialize the environment. libc.so gets initialized after us due to a | |
118 | + circular dependency and hence __environ is not available otherwise. */ | |
119 | + __environ = envp; | |
120 | ||
121 | - /* Make sure it meets the minimum size that allocate_stack | |
122 | - (allocatestack.c) will demand, which depends on the page size. */ | |
123 | - const uintptr_t pagesz = __sysconf (_SC_PAGESIZE); | |
124 | - const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK; | |
125 | - if (limit.rlim_cur < minstack) | |
126 | - limit.rlim_cur = minstack; | |
127 | +#ifndef SHARED | |
128 | + __libc_init_secure (); | |
129 | +#endif | |
130 | ||
131 | - /* Round the resource limit up to page size. */ | |
132 | - limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz; | |
133 | - __default_pthread_attr.stacksize = limit.rlim_cur; | |
134 | + /* Get the default stack size from the environment variable if it is set and | |
135 | + is valid. */ | |
136 | + size_t stacksize = 0; | |
137 | + char *envval = __secure_getenv ("GLIBC_PTHREAD_STACKSIZE"); | |
138 | + | |
139 | + if (__builtin_expect (envval != NULL && envval[0] != '\0', 0)) | |
140 | + { | |
141 | + char *env_conv = envval; | |
142 | + size_t ret = strtoul (envval, &env_conv, 0); | |
143 | + | |
144 | + if (*env_conv == '\0' && env_conv != envval) | |
145 | + stacksize = ret; | |
146 | + } | |
147 | + | |
148 | + if (stacksize == 0) | |
149 | + { | |
150 | + /* Determine the default allowed stack size. */ | |
151 | + struct rlimit limit; | |
152 | + if (getrlimit (RLIMIT_STACK, &limit) != 0 | |
153 | + || limit.rlim_cur == RLIM_INFINITY) | |
154 | + /* The system limit is not usable. Use an architecture-specific | |
155 | + default. */ | |
156 | + stacksize = ARCH_STACK_DEFAULT_SIZE; | |
157 | + else | |
158 | + stacksize = limit.rlim_cur; | |
159 | + } | |
160 | + | |
161 | + /* Finally, set the default stack size. This size is used when the user does | |
162 | + not specify a stack size during thread creation. */ | |
163 | + set_default_stacksize (stacksize); | |
164 | __default_pthread_attr.guardsize = GLRO (dl_pagesize); | |
165 | ||
166 | #ifdef SHARED | |
167 | diff -pruN glibc-2.12-2-gc4ccff1/nptl/tst-default-attr.c glibc-2.12-2-gc4ccff1.fixed/nptl/tst-default-attr.c | |
168 | --- glibc-2.12-2-gc4ccff1/nptl/tst-default-attr.c 1970-01-01 05:30:00.000000000 +0530 | |
169 | +++ glibc-2.12-2-gc4ccff1.fixed/nptl/tst-default-attr.c 2013-07-09 23:34:59.598859295 +0530 | |
170 | @@ -0,0 +1,109 @@ | |
171 | +/* Verify that default stack size gets set correctly from the environment | |
172 | + variable. | |
173 | + | |
174 | + Copyright (C) 2013 Free Software Foundation, Inc. | |
175 | + This file is part of the GNU C Library. | |
176 | + | |
177 | + The GNU C Library is free software; you can redistribute it and/or | |
178 | + modify it under the terms of the GNU Lesser General Public | |
179 | + License as published by the Free Software Foundation; either | |
180 | + version 2.1 of the License, or (at your option) any later version. | |
181 | + | |
182 | + The GNU C Library is distributed in the hope that it will be useful, | |
183 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
184 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
185 | + Lesser General Public License for more details. | |
186 | + | |
187 | + You should have received a copy of the GNU Lesser General Public | |
188 | + License along with the GNU C Library; if not, see | |
189 | + <http://www.gnu.org/licenses/>. */ | |
190 | + | |
191 | +#include <pthread.h> | |
192 | +#include <stdio.h> | |
193 | +#include <stdint.h> | |
194 | +#include <string.h> | |
195 | +#include <unistd.h> | |
196 | +#include <errno.h> | |
197 | + | |
198 | +#define RETURN_IF_FAIL(f, ...) \ | |
199 | + ({ \ | |
200 | + int ret = f (__VA_ARGS__); \ | |
201 | + if (ret != 0) \ | |
202 | + { \ | |
203 | + printf ("%s:%d: %s returned %d (errno = %d)\n", __FILE__, __LINE__, \ | |
204 | + #f, ret, errno); \ | |
205 | + return ret; \ | |
206 | + } \ | |
207 | + }) | |
208 | + | |
209 | +/* DEFAULT_STACKSIZE macro is defined in the Makefile. */ | |
210 | +static size_t stacksize = DEFAULT_STACKSIZE; | |
211 | + | |
212 | +static int | |
213 | +verify_stacksize_result (pthread_attr_t *attr) | |
214 | +{ | |
215 | + size_t stack; | |
216 | + | |
217 | + RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack); | |
218 | + | |
219 | + if (stacksize != stack) | |
220 | + { | |
221 | + printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack); | |
222 | + return 1; | |
223 | + } | |
224 | + | |
225 | + return 0; | |
226 | +} | |
227 | + | |
228 | +static void * | |
229 | +thr (void *unused __attribute__ ((unused))) | |
230 | +{ | |
231 | + pthread_attr_t attr; | |
232 | + int ret; | |
233 | + | |
234 | + memset (&attr, 0xab, sizeof attr); | |
235 | + /* To verify that the attributes actually got applied. */ | |
236 | + if ((ret = pthread_getattr_np (pthread_self (), &attr)) != 0) | |
237 | + { | |
238 | + printf ("pthread_getattr_np failed: %s\n", strerror (ret)); | |
239 | + goto out; | |
240 | + } | |
241 | + | |
242 | + ret = verify_stacksize_result (&attr); | |
243 | + | |
244 | +out: | |
245 | + return (void *) (uintptr_t) ret; | |
246 | +} | |
247 | + | |
248 | +static int | |
249 | +run_threads (void) | |
250 | +{ | |
251 | + pthread_t t; | |
252 | + void *tret = NULL; | |
253 | + | |
254 | + /* Run twice to ensure that the attributes do not get overwritten in the | |
255 | + first run somehow. */ | |
256 | + for (int i = 0; i < 2; i++) | |
257 | + { | |
258 | + RETURN_IF_FAIL (pthread_create, &t, NULL, thr, NULL); | |
259 | + RETURN_IF_FAIL (pthread_join, t, &tret); | |
260 | + | |
261 | + if (tret != NULL) | |
262 | + { | |
263 | + puts ("Thread failed"); | |
264 | + return 1; | |
265 | + } | |
266 | + } | |
267 | + | |
268 | + return 0; | |
269 | +} | |
270 | + | |
271 | +static int | |
272 | +do_test (void) | |
273 | +{ | |
274 | + RETURN_IF_FAIL (run_threads); | |
275 | + return 0; | |
276 | +} | |
277 | + | |
278 | +#define TEST_FUNCTION do_test () | |
279 | +#include "../test-skeleton.c" |