在 Debian 上调试 readdir 相关问题(目录读取异常、返回错误、挂起、缺文件等),可以按下面思路系统性排查。
readdir 有多种形态,先分清:
| 场景 | 说明 |
|---|---|
glibc readdir() / readdir_r() |
用户态接口 |
getdents() / getdents64() |
系统调用 |
| 内核 VFS / 文件系统 | ext4 / xfs / nfs / overlay |
| 硬件 / 存储 | 磁盘、网络、FUSE |
常见问题包括:
readdir 返回 NULL 但 errno 不明确readdir 卡住不返回ls / strace 复现ls -la problem_dir
strace ls problem_dir
关注:
getdents*EIO, ENOENT, ESTALE#include <dirent.h>
#include <stdio.h>
#include <errno.h>
int main() {
DIR *dir = opendir(".");
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *entry;
errno = 0;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
if (errno != 0) {
perror("readdir");
}
closedir(dir);
return 0;
}
说明:
readdir() 返回 NULL 时,必须检查 errnoerrno == 0 → 正常结束errno != 0 → 出错strace ./readdir_test
重点看:
getdents(3, ....)
返回值:
EIO → 文件系统错误ENOENT → 目录被删ESTALE → NFS 句柄失效dmesg -T | tail -100
journalctl -k
常见错误:
ext4_errorI/O errorNFS: server not respondingdf -hT
如果是 ext4:
umount /mountpoint
fsck.ext4 -f /dev/sdX
如果是 NFS:
mount | grep nfs
问题:
readdir 返回 ESTALE处理:
mount -o remount,hard,intr,timeo=30
或:
nfsvers=3 或 4.2)nfsd / 服务端常见于 Docker / Podman:
mount | grep overlay
表现:
readdir 顺序异常解决:
ls 对比 upper / lowerltraceltrace ./readdir_test
查看:
readdir() 返回值malloc 是否失败perf top / perf traceperf trace ./readdir_test
查看系统调用延迟。
root / 普通用户)| 现象 | 可能原因 |
|---|---|
readdir 返回空 |
权限不足 |
EIO |
磁盘 / FS 错误 |
ESTALE |
NFS |
| 卡死 | NFS / FUSE |
| 目录少文件 | overlay / 缓存 |
| 随机失败 | 多线程重用 DIR* |
可以直接贴出:
strace 输出我可以帮你精准定位是 用户态 bug、glibc、内核还是存储问题。