summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2010-09-19 05:19:47 +0000
committerdavidxu <davidxu@FreeBSD.org>2010-09-19 05:19:47 +0000
commitad24f558bd7b034d0376f20da562ae31ddfe68b1 (patch)
tree47623deb3552808a7fe4395dec19f249ad2c4c3f /lib/libthr
parenteebc7df64cafec4f2e406fa12be1388c91175299 (diff)
downloadFreeBSD-src-ad24f558bd7b034d0376f20da562ae31ddfe68b1.zip
FreeBSD-src-ad24f558bd7b034d0376f20da562ae31ddfe68b1.tar.gz
Fix a race condition when finding stack unwinding functions.
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_exit.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/libthr/thread/thr_exit.c b/lib/libthr/thread/thr_exit.c
index 2ff3953..83188c8 100644
--- a/lib/libthr/thread/thr_exit.c
+++ b/lib/libthr/thread/thr_exit.c
@@ -70,18 +70,31 @@ static void
thread_uw_init(void)
{
static int inited = 0;
+ Dl_info dlinfo;
void *handle;
+ void *forcedunwind, *resume, *getcfa;
if (inited)
- return;
- inited = 1;
+ return;
handle = RTLD_DEFAULT;
- if ((uwl_forcedunwind = dlsym(handle, "_Unwind_ForcedUnwind")) == NULL||
- (uwl_resume = dlsym(handle, "_Unwind_Resume")) == NULL ||
- (uwl_getcfa = dlsym(handle, "_Unwind_GetCFA")) == NULL) {
- uwl_forcedunwind = NULL;
- return;
+ if ((forcedunwind = dlsym(handle, "_Unwind_ForcedUnwind")) != NULL) {
+ if (dladdr(forcedunwind, &dlinfo)) {
+ if ((handle = dlopen(dlinfo.dli_fname, RTLD_LAZY)) != NULL) {
+ forcedunwind = dlsym(handle, "_Unwind_ForcedUnwind");
+ resume = dlsym(handle, "_Unwind_Resume");
+ getcfa = dlsym(handle, "_Unwind_GetCFA");
+ if (forcedunwind != NULL && resume != NULL &&
+ getcfa != NULL) {
+ uwl_forcedunwind = forcedunwind;
+ uwl_resume = resume;
+ uwl_getcfa = getcfa;
+ } else {
+ dlclose(handle);
+ }
+ }
+ }
}
+ inited = 1;
}
void
OpenPOWER on IntegriCloud