This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit f2a186ee5f03ce1526bb126681f104277879549c Author: Marco Casaroli <[email protected]> AuthorDate: Tue Oct 13 06:56:55 2026 +0200 libs/libc/elf: Keep the last reference when a close fails. libelf_remove() set the reference count of a module to zero before libelf_uninit() refused to unload it because other modules depend on it. The failed dlclose() thus gave up the last reference anyway. When the last dependent went, libelf_undepend() unloaded the module, and the next dlclose() of the still open handle failed with ENOENT. examples/sotest shows it: "ERROR: dlclose(handle1) failed: -1". Refuse with EBUSY before the reference is given up, and keep the reference if the uninitializer of the module fails. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- libs/libc/elf/elf_remove.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libs/libc/elf/elf_remove.c b/libs/libc/elf/elf_remove.c index 82d64746e28..ad00ef99fcb 100644 --- a/libs/libc/elf/elf_remove.c +++ b/libs/libc/elf/elf_remove.c @@ -257,12 +257,26 @@ int libelf_remove(FAR void *handle) return OK; } +#if CONFIG_LIBC_ELF_MAXDEPEND > 0 + /* The last reference stays while other modules depend on this one: a + * failed close must not let the module go later, under the caller. + */ + + if (modp->dependents > 0) + { + berr("ERROR: Module has dependents: %d\n", modp->dependents); + ret = -EBUSY; + goto errout_with_lock; + } +#endif + modp->nopen = 0; ret = libelf_uninit(modp); if (ret < 0) { berr("ERROR: Failed to uninitialize module %d\n", ret); + modp->nopen = 1; goto errout_with_lock; }
