Skip to content

Commit

Permalink
Fix the problem with the C++ exception handling for the multithreaded
Browse files Browse the repository at this point in the history
programs.

From the PR description:
The gcc runtime's _Unwind_Find_FDE function, invoked during exception
handling's stack unwinding, is not safe to execute from within multiple
threads. FreeBSD' s dl_iterate_phdr() however permits multiple threads
to pass through it though. The result is surprisingly reliable infinite
looping of one or more threads if they just happen to be unwinding at
the same time.

Introduce the new lock that is write locked around the dl_iterate_pdr,
thus providing required exclusion for the stack unwinders.

PR:	threads/123062
Submitted by:	Andy Newman <an at atrn org>
Reviewed by:	kan
MFC after:	2 weeks
  • Loading branch information
kostikbel committed May 6, 2008
1 parent fc58e99 commit 60e5d7d
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 4 deletions.
8 changes: 5 additions & 3 deletions libexec/rtld-elf/rtld.c
Expand Up @@ -2129,9 +2129,10 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
{
struct dl_phdr_info phdr_info;
const Obj_Entry *obj;
int error, lockstate;
int error, bind_lockstate, phdr_lockstate;

lockstate = rlock_acquire(rtld_bind_lock);
phdr_lockstate = wlock_acquire(rtld_phdr_lock);
bind_lockstate = rlock_acquire(rtld_bind_lock);

error = 0;

Expand All @@ -2150,7 +2151,8 @@ dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
break;

}
rlock_release(rtld_bind_lock, lockstate);
rlock_release(rtld_bind_lock, bind_lockstate);
wlock_release(rtld_phdr_lock, phdr_lockstate);

return (error);
}
Expand Down
3 changes: 2 additions & 1 deletion libexec/rtld-elf/rtld_lock.c
Expand Up @@ -171,14 +171,15 @@ thread_mask_clear(int mask)
lockinfo.thread_clr_flag(mask);
}

#define RTLD_LOCK_CNT 2
#define RTLD_LOCK_CNT 3
struct rtld_lock {
void *handle;
int mask;
} rtld_locks[RTLD_LOCK_CNT];

rtld_lock_t rtld_bind_lock = &rtld_locks[0];
rtld_lock_t rtld_libc_lock = &rtld_locks[1];
rtld_lock_t rtld_phdr_lock = &rtld_locks[2];

int
rlock_acquire(rtld_lock_t lock)
Expand Down
1 change: 1 addition & 0 deletions libexec/rtld-elf/rtld_lock.h
Expand Up @@ -52,6 +52,7 @@ typedef struct rtld_lock *rtld_lock_t;

extern rtld_lock_t rtld_bind_lock;
extern rtld_lock_t rtld_libc_lock;
extern rtld_lock_t rtld_phdr_lock;

int rlock_acquire(rtld_lock_t);
int wlock_acquire(rtld_lock_t);
Expand Down

0 comments on commit 60e5d7d

Please sign in to comment.