aboutsummaryrefslogtreecommitdiff
path: root/lib/libthr
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2011-01-10 16:10:25 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2011-01-10 16:10:25 +0000
commitfad128db86ae3b5790eef4f400720822b8754df1 (patch)
tree7b3832f55586523f0e163291a10e86e5c25bdbe1 /lib/libthr
parentbf390c1fbd0c9e7b2c344d43aa010e03a67277c8 (diff)
downloadsrc-fad128db86ae3b5790eef4f400720822b8754df1.tar.gz
src-fad128db86ae3b5790eef4f400720822b8754df1.zip
For the process that already loaded libthr but still not initialized
threading, fall back to libc method of performing __pthread_map_stacks_exec() job. Reported and tested by: Mykola Dzham <i levsha me>
Notes
Notes: svn path=/head/; revision=217224
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_stack.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c
index cb390cc06d87..15a9c82ef027 100644
--- a/lib/libthr/thread/thr_stack.c
+++ b/lib/libthr/thread/thr_stack.c
@@ -30,6 +30,8 @@
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
#include <stdlib.h>
#include <pthread.h>
#include <link.h>
@@ -139,6 +141,26 @@ _thr_stack_fix_protection(struct pthread *thrd)
_rtld_get_stack_prot());
}
+static void
+singlethread_map_stacks_exec(void)
+{
+ int mib[2];
+ struct rlimit rlim;
+ u_long usrstack;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_USRSTACK;
+ len = sizeof(usrstack);
+ if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0)
+ == -1)
+ return;
+ if (getrlimit(RLIMIT_STACK, &rlim) == -1)
+ return;
+ mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur),
+ rlim.rlim_cur, _rtld_get_stack_prot());
+}
+
void __pthread_map_stacks_exec(void);
void
__pthread_map_stacks_exec(void)
@@ -146,6 +168,10 @@ __pthread_map_stacks_exec(void)
struct pthread *curthread, *thrd;
struct stack *st;
+ if (!_thr_is_inited()) {
+ singlethread_map_stacks_exec();
+ return;
+ }
curthread = _get_curthread();
THREAD_LIST_RDLOCK(curthread);
LIST_FOREACH(st, &mstackq, qe)