Work around an assert failure in the dynamic linker's default thread
locking functions. If an application loads a shared object with dlopen() and the shared object has an init function which requires lazy binding, then _rtld_bind is called when the thread is already inside the dynamic linker. This leads to a recursive acquisition of the lock, which I was not expecting -- hence the assert failure. This work-around makes the default locking functions handle recursive locking. It is NOT the correct fix -- that should be implemented at the generic locking level rather than in the default locking functions. I will implement the correct fix in a future commit. Since the dllockinit() interface will likely need to change, warn about that in both the man page and the header file.
This commit is contained in:
parent
427db879c9
commit
3600eb76c6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55165
@ -66,6 +66,7 @@ __BEGIN_DECLS
|
|||||||
int dladdr __P((const void *, Dl_info *));
|
int dladdr __P((const void *, Dl_info *));
|
||||||
int dlclose __P((void *));
|
int dlclose __P((void *));
|
||||||
const char *dlerror __P((void));
|
const char *dlerror __P((void));
|
||||||
|
/* XXX dllockinit() interface is likely to change. */
|
||||||
void dllockinit __P((void *_context,
|
void dllockinit __P((void *_context,
|
||||||
void *(*_lock_create)(void *_context),
|
void *(*_lock_create)(void *_context),
|
||||||
void (*_rlock_acquire)(void *_lock),
|
void (*_rlock_acquire)(void *_lock),
|
||||||
|
@ -39,6 +39,10 @@
|
|||||||
"void (*lock_release)(void *lock)" "void (*lock_destroy)(void *lock)" \
|
"void (*lock_release)(void *lock)" "void (*lock_destroy)(void *lock)" \
|
||||||
"void (*context_destroy)(void *context)"
|
"void (*context_destroy)(void *context)"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
.Bf Sy
|
||||||
|
This interface is subject to change and should not be used yet.
|
||||||
|
.Ef
|
||||||
|
.Pp
|
||||||
Threads packages can call
|
Threads packages can call
|
||||||
.Nm
|
.Nm
|
||||||
at initialization time to register locking functions for the dynamic
|
at initialization time to register locking functions for the dynamic
|
||||||
|
@ -51,8 +51,11 @@ void
|
|||||||
lockdflt_acquire(void *lock)
|
lockdflt_acquire(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
|
sigset_t old_mask;
|
||||||
assert(l->depth == 0);
|
|
||||||
|
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
|
||||||
|
if (l->depth == 0)
|
||||||
|
l->old_mask = old_mask;
|
||||||
l->depth++;
|
l->depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +84,10 @@ void
|
|||||||
lockdflt_release(void *lock)
|
lockdflt_release(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
assert(l->depth == 1);
|
|
||||||
l->depth--;
|
l->depth--;
|
||||||
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
assert(l->depth >= 0);
|
||||||
|
if (l->depth == 0)
|
||||||
|
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -51,8 +51,11 @@ void
|
|||||||
lockdflt_acquire(void *lock)
|
lockdflt_acquire(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
|
sigset_t old_mask;
|
||||||
assert(l->depth == 0);
|
|
||||||
|
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
|
||||||
|
if (l->depth == 0)
|
||||||
|
l->old_mask = old_mask;
|
||||||
l->depth++;
|
l->depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +84,10 @@ void
|
|||||||
lockdflt_release(void *lock)
|
lockdflt_release(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
assert(l->depth == 1);
|
|
||||||
l->depth--;
|
l->depth--;
|
||||||
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
assert(l->depth >= 0);
|
||||||
|
if (l->depth == 0)
|
||||||
|
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -51,8 +51,11 @@ void
|
|||||||
lockdflt_acquire(void *lock)
|
lockdflt_acquire(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
|
sigset_t old_mask;
|
||||||
assert(l->depth == 0);
|
|
||||||
|
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
|
||||||
|
if (l->depth == 0)
|
||||||
|
l->old_mask = old_mask;
|
||||||
l->depth++;
|
l->depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +84,10 @@ void
|
|||||||
lockdflt_release(void *lock)
|
lockdflt_release(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
assert(l->depth == 1);
|
|
||||||
l->depth--;
|
l->depth--;
|
||||||
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
assert(l->depth >= 0);
|
||||||
|
if (l->depth == 0)
|
||||||
|
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -51,8 +51,11 @@ void
|
|||||||
lockdflt_acquire(void *lock)
|
lockdflt_acquire(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
|
sigset_t old_mask;
|
||||||
assert(l->depth == 0);
|
|
||||||
|
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
|
||||||
|
if (l->depth == 0)
|
||||||
|
l->old_mask = old_mask;
|
||||||
l->depth++;
|
l->depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +84,10 @@ void
|
|||||||
lockdflt_release(void *lock)
|
lockdflt_release(void *lock)
|
||||||
{
|
{
|
||||||
LockDflt *l = (LockDflt *)lock;
|
LockDflt *l = (LockDflt *)lock;
|
||||||
assert(l->depth == 1);
|
|
||||||
l->depth--;
|
l->depth--;
|
||||||
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
assert(l->depth >= 0);
|
||||||
|
if (l->depth == 0)
|
||||||
|
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user