-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Open
Description
RT-Thread Version
Master
Hardware Type/Architectures
STM32F407
Develop Toolchain
RT-Thread Studio
Describe the bug
dfs/filesystems/elmfat/dfs_elm.c文件中的dfs_elm_open和dfs_elm_close函数在处理文件引用计数 (ref_count) 时的行为不一致,导致了严重的内存泄漏。
问题根源分析:
dfs_elm_open的行为: 无论一个文件被打开多少次 (ref_count值是多少),dfs_elm_open函数总是会为每一次open调用执行rt_malloc来分配一个新的底层文件句柄 (FIL或DIR结构体)。dfs_elm_close的行为: 与open的行为相反,dfs_elm_close函数在开始处包含一个检查if (file->vnode->ref_count > 1)。如果这个条件成立(意味着还有其他文件描述符指向同一个文件),函数会直接返回,并不会调用rt_free来释放当初为这个文件描述符在open时所分配的内存。
导致的后果:
这种 open (总是分配) 和 close (有条件释放) 之间的逻辑不对称,导致对同一个文件进行多次打开后,除了最后一次关闭操作外,之前所有的关闭操作都会跳过资源释放步骤,造成与关闭次数成正比的内存泄漏。
Steps to reproduce the behavior (复现步骤)
- 分析代码发现,尚未测试
- 该部分逻辑与littlefs类似,littlefs处理不会导致malloc与free不一致问题,但是会导致第二次open失败
Expected behavior (预期行为)
每一次 close(fd) 调用都应该精确地释放与之对应的 open() 操作所分配的内存资源 (FIL 或 DIR 结构体)。在上述测试代码的循环中,initial_mem 和 final_mem 的值应该保持一致(不考虑系统其他任务的微小波动),不应出现累积性的内存增长。
Add screenshot / media if you have them (截图)
(无)
Other additional context
这个问题的根源在于 dfs_elm.c 文件中 dfs_elm_close 函数的以下代码块:
int dfs_elm_close(struct dfs_file *file)
{
FRESULT result;
RT_ASSERT(file->vnode->ref_count > 0);
if (file->vnode->ref_count > 1)
{
return 0; // <--- 此处直接返回,导致内存泄漏
}
// ... 后续的释放逻辑 ...
}建议的修复方案是直接移除这个 if (file->vnode->ref_count > 1) 判断,以确保 open 和 close 的资源管理行为是对称的。
另外,还有一个相关的逻辑不一致点:在 dfs_elm_open 函数中,对 ref_count 的检查仅在 FF_VOLUMES > 1 的宏条件下存在,而在单卷配置下则没有。虽然这不是导致内存泄漏的直接原因,但建议一并修复,以保证代码在不同配置下行为的统一性。
Metadata
Metadata
Assignees
Labels
No labels