NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: PR lib/59751: dlclose is not MT-safe depending on the libraries unloaded
> Date: Wed, 15 Jul 2026 23:54:56 +0200
> From: Anthony Mallet <anthony.mallet%laas.fr@localhost>
>
> I was actually trying to debug dlclose(3) issues in a complex C++
> program (not related to this PR at all). Then I found this report and
> the associated recent commits, so I gave it a try as it looked
> promising for my case too.
>
> Now, (with -current and ld.elf_so from today) it seems that
> _recursive_ dlclose() calls blocks infinitely. I can try to provide
> a minimal reproducer, but I wanted to let you know first, in case you can
> quickly spot or figure out the issue.
Darnit! That's probably much worse than requiring the caller to
serialize dlopen/dlclose, which was an effective workaround for the
original problem this PR was about...
> Note that the recursive dlclose, as weird as it looks, is expected to
> happen given the way the code is written. The two dlclose are not
> targetting the same libraries, although both libraries have many
> dependencies in common. I'm not sure if recursive dlclose is not
> undefined behaviour though.
I don't know if it's really defined by a standard but it's a
reasonable thing to do.
Can you try the attached patch and see if it works in your complex
application?
I haven't really thought through the implications but it makes a
simple test pass.
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1784160130 0
# Thu Jul 16 00:02:10 2026 +0000
# Branch trunk
# Node ID cd0994f0feb0884c98f4ab9523142cd99fabde47
# Parent 05f0f4cd0342e5f669a0e3bfdb589842a248e4a4
# EXP-Topic riastradh-pr59751-recursivedlopendlclose
WIP: dlfcn(3): Allow recursive dlopen/dclose again through init/fini.
PR lib/59751: dlclose is not MT-safe depending on the libraries
unloaded
diff -r 05f0f4cd0342 -r cd0994f0feb0 libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c Wed Jul 15 23:56:27 2026 +0000
+++ b/libexec/ld.elf_so/rtld.c Thu Jul 16 00:02:10 2026 +0000
@@ -529,6 +529,8 @@ restart:
if (obj->refcount > 0 && !force) {
continue;
}
+ if (obj->initfinilock == _lwp_self())
+ continue;
if (!_rtld_initfini_enter(&obj, mask)) {
_rtld_objlist_clear(&finilist);
goto restart;
@@ -549,6 +551,8 @@ restart:
if (obj->refcount > 0 && !force) {
continue;
}
+ if (obj->initfinilock == _lwp_self())
+ continue;
if (!_rtld_initfini_enter(&obj, mask)) {
_rtld_objlist_clear(&finilist);
goto restart;
@@ -600,6 +604,8 @@ static void
static bool
_rtld_call_ifunc_functions(sigset_t *mask, Obj_Entry *obj, u_int cur_objgen)
{
+ if (obj->initfinilock == _lwp_self())
+ return false;
if (!_rtld_initfini_enter(&obj, mask))
return true;
if (obj->ifunc_remaining
@@ -683,6 +689,8 @@ restart:
goto restart;
}
if (obj->z_initfirst) {
+ if (obj->initfinilock == _lwp_self())
+ continue;
if (!_rtld_initfini_enter(&obj, mask)) {
_rtld_objlist_clear(&initlist);
goto restart;
@@ -704,6 +712,8 @@ restart:
_rtld_objlist_clear(&initlist);
goto restart;
}
+ if (obj->initfinilock == _lwp_self())
+ continue;
if (!_rtld_initfini_enter(&obj, mask)) {
_rtld_objlist_clear(&initlist);
goto restart;
diff -r 05f0f4cd0342 -r cd0994f0feb0 tests/libexec/ld.elf_so/t_dlclose_thread.c
--- a/tests/libexec/ld.elf_so/t_dlclose_thread.c Wed Jul 15 23:56:27 2026 +0000
+++ b/tests/libexec/ld.elf_so/t_dlclose_thread.c Thu Jul 16 00:02:10 2026 +0000
@@ -116,13 +116,6 @@ ATF_TC_BODY(dlclose_recursive, tc)
RL(timer_create(CLOCK_MONOTONIC, &sigev, &t));
RL(timer_settime(t, TIMER_RELTIME, &it, NULL));
- /*
- * Really, the issue is the followup to the fix for the PR
- * which is that I broke recursive dlopen/dlclose!
- */
- atf_tc_expect_signal(SIGABRT, "PR lib/59751: dlclose is not MT-safe"
- " depending on the libraries unloaded");
-
handle = dlopen("libh_helper_recurdso.so", RTLD_LAZY | RTLD_LOCAL);
ATF_REQUIRE_MSG(handle != NULL, "%s", dlerror());
ATF_REQUIRE_MSG((error = dlclose(handle)) == 0,
Home |
Main Index |
Thread Index |
Old Index