[libc][libdl] Fix dlopen() failing to find already-loaded modules#11269
Draft
[libc][libdl] Fix dlopen() failing to find already-loaded modules#11269
Conversation
|
|
Fix name mismatch between dlmodule_find() and _dlmodule_set_name() that caused dlopen() to always reload modules instead of reusing them: 1. In dlopen(): Extract module name from full path before calling dlmodule_find(), matching the stripped name stored by _dlmodule_set_name(). This allows dlopen() to properly find and reuse already-loaded modules. 2. In _dlmodule_set_name(): Fix bug where extension detection searched the entire path instead of just the filename portion. For paths like "/mnt/v1.2/app.so", it would incorrectly find "." in "v1.2" directory name instead of the ".so" extension. Fixes: Module reloading on every dlopen() call, memory leaks from duplicate module instances, and dlclose() cleanup issues. Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
… cases Address code review feedback: 1. Extract path stripping logic into shared dlmodule_extract_name() function to avoid code duplication between dlopen() and _dlmodule_set_name(). 2. Fix edge case handling for filenames starting with dot (e.g., .hidden). 3. Add proper documentation for the new function. This ensures consistent module name extraction across all code paths. Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
…_name Clarify the behavior of edge cases in documentation: - Added more examples to the function documentation - Fixed misleading comment about dot handling - Clarified the defensive check purpose Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] [Bug] Fix dlopen() fails to find already-loaded module
[libc][libdl] Fix dlopen() failing to find already-loaded modules
Mar 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dlopen()passes the full path todlmodule_find(), but_dlmodule_set_name()stores only the stripped basename. The lookup always fails, causing modules to reload on every call withnref++never reached.Changes
New
dlmodule_extract_name()function — Extracts module name from path, stripping directory and extension. Shared betweendlopen()and_dlmodule_set_name()to ensure consistent naming.Fix extension detection — Original code found last
.in entire path, not filename./mnt/v1.2/app.soincorrectly extractedv1instead ofapp.Edge case handling — Hidden files like
.hiddenuse entire filename;.hidden.sostrips to.hidden.Before/After
/mnt/sdcard/apps/clock.soclock❌clock✓/mnt/v1.2/app.sov1(bug)appOriginal prompt
This section details on the original issue you should resolve
<issue_title>[Bug] dlopen() fails to find already-loaded module — name mismatch between dlmodule_find() and _dlmodule_set_name()</issue_title>
<issue_description>### RT-Thread Version
master (latest)
Hardware Type/Architectures
N/A — platform-independent logic bug in components/libc/posix/libdl/
Develop Toolchain
Microsoft VScode
Describe the bug
Bug Description
Summary
When
dlopen()is called with a full file path (e.g."/mnt/sdcard/apps/clock.so"), it passes the full path todlmodule_find()for lookup. However, during module loading,_dlmodule_set_name()strips the path and extension, storing only the bare filename (e.g."clock") intomodule->parent.name. Sincedlmodule_find()usesrt_object_find()which matches againstobject->name, the lookup always fails for previously loaded modules.This causes:
dlopen()call — thenref++branch is never reacheddlclose()cannot properly clean up — eachdlopen()returns a different handle pointing to a different copyRoot Cause Analysis
Step 1:
dlopen()passes full path todlmodule_find()File:
dlopen.c, line 38-44Step 2:
dlmodule_find()does direct name matching with no path processingFile:
dlmodule.c, line 1130-1142Step 3:
_dlmodule_set_name()strips path and extension before storingFile:
dlmodule.c, line 74-99The Mismatch
dlmodule_find()query"/mnt/sdcard/apps/clock.so"object->namestored by_dlmodule_set_name()"clock"These will never match.
Steps to Reproduce
Expected Behavior
The second
dlopen()call should find the already-loaded module, incrementnref, and return the same module handle.Actual Behavior
Every
dlopen()call with a full path loads a new copy of the module. Thenref++reuse branch indlopen()is effectively dead code —nrefis only ever incremented to 1 insidedlmodule_load()itself (line 753), but never reaches 2+ through the intendeddlopen()reuse path.Suggested Fix
Apply the same path-stripping logic before calling
dlmodule_find()indlopen(). Minimal patch: