温馨提示×

ubuntu readdir如何调试

小樊
37
2026-10-09 13:33:25
栏目: 智能运维

在 Ubuntu(Linux)下调试 readdir(通常指 readdir(3) / readdir_r / opendir + readdir)相关问题时,可以按下面几个层面来做。


一、先确认你用的是哪个 readdir

常见有几种:

  • C 标准库:opendir() / readdir() / closedir()
  • 系统调用:getdents() / getdents64()
  • Shell 命令:ls(内部也可能用到 readdir)

调试前先明确:

man readdir
man getdents

二、最基本的代码调试方法

1. 打开 errno 和 perror

readdir 出错时通常靠 errno:

#include <dirent.h>
#include <errno.h>
#include <stdio.h>

DIR *dir = opendir("/path");
if (!dir) {
    perror("opendir");
    return 1;
}

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    printf("name: %s, type: %d\n", entry->d_name, entry->d_type);
}

if (errno != 0) {
    perror("readdir");
}

closedir(dir);

2. 打印 d_type / inode 信息

#include <dirent.h>

switch (entry->d_type) {
    case DT_REG: printf("file\n"); break;
    case DT_DIR: printf("dir\n"); break;
    case DT_LNK: printf("symlink\n"); break;
    default: printf("other\n");
}

三、用 strace 看系统调用(最常用)

readdir 最终会调用 getdents64:

strace -e trace=file your_program

或只看目录相关:

strace -e openat,getdents64,readdir your_program

示例输出:

openat(AT_FDCWD, "/path", O_RDONLY|O_DIRECTORY) = 3
getdents64(3, /* 10 entries */, 32768) = 1234

如果看到:

  • ENOENT:路径不存在
  • EACCES:权限不足
  • EMFILE / ENFILE:文件描述符耗尽

四、用 ltrace 看库函数调用

ltrace -e readdir your_program

可以看到:

readdir(0x55a1c) = 0x7f...

五、GDB 调试 readdir

1. 编译带调试信息

gcc -g -o test test.c

2. 使用 GDB

gdb ./test

在 readdir 处打断点:

break readdir
run
step
print entry

如果是静态链接或内联,可能要:

break opendir
break closedir

六、检查目录本身的问题

1. 目录是否存在、权限是否正确

ls -ld /path

2. 是否为挂载点 / 网络目录

mount | grep path

NFS / FUSE 下 readdir 行为可能异常。


七、常见坑点

1. readdir 不是线程安全的

多线程请用:

readdir_r(dir, entry, &result);

2. readdir 返回 NULL 不一定出错

要用 errno 判断:

errno = 0;
entry = readdir(dir);
if (!entry && errno != 0) {
    perror("readdir");
}

3. 符号链接目录

d_type == DT_LNK,需要 stat 进一步判断。


八、快速自测小程序(推荐)

#include <dirent.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    if (argc < 2) return 1;
    DIR *d = opendir(argv[1]);
    if (!d) { perror("opendir"); return 1; }

    struct dirent *e;
    errno = 0;
    while ((e = readdir(d))) {
        printf("%s\n", e->d_name);
    }
    if (errno) perror("readdir");
    closedir(d);
    return 0;
}

如果你愿意,可以把:

  • 报错信息
  • 示例代码
  • Ubuntu 版本

发出来,我可以帮你具体分析是哪一步出问题。

0 踩