在 Debian(或其他 Linux 系统)上调试 opendir() 相关的问题,通常可以从代码层面、系统调用层面、权限/环境层面三个方向入手。下面给你一套比较实用的调试方法。
opendir() 的基本用法:
#include <dirent.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
DIR *dir = opendir(argv[1]);
if (dir == NULL) {
perror("opendir");
return 1;
}
closedir(dir);
return 0;
}
NULLperror() / strerror() 看错误原因(最常用)if ((dir = opendir(path)) == NULL) {
perror("opendir");
}
运行示例:
./a.out /root
输出:
opendir: Permission denied
常见 errno:
ENOENT:目录不存在EACCES:权限不足ENOTDIR:不是目录EMFILE / ENFILE:文件描述符耗尽strace 跟踪系统调用(非常推荐)sudo apt install strace
strace ./your_program /some/path
重点看:
openat(AT_FDCWD, "/some/path", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 EACCES
可以直接看到:
ls -ld /path/to/dir
namei -l /path/to/dir
每一级目录都需要:
x(进入目录)r(读取目录内容)Debian 默认用 AppArmor:
sudo aa-status
sudo apt install gdb
gdb ./your_program
run /some/path
bt
print errno
或者在 opendir 后打断点:
break opendir
run
如果是库里的问题:
ldd ./your_program
确认链接的是正确的 libc:
ls -l /lib/x86_64-linux-gnu/libc.so.6
opendir("/proc/self/fd") 受限可以测试:
stat /path/to/dir
#define _GNU_SOURCE
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "usage: %s <dir>\n", argv[0]);
return 1;
}
DIR *d = opendir(argv[1]);
if (!d) {
fprintf(stderr, "opendir(%s) failed: %s\n",
argv[1], strerror(errno));
return 1;
}
closedir(d);
return 0;
}
如果你愿意,可以把:
cat /etc/debian_version)发出来,我可以更具体地帮你定位问题。