1

readdir()在嵌入式应用程序中出现了一些问题,因此我在应用程序代码的一个方便位置添加了这个独立的测试:

FILE *f;
DIR *d;

f = fopen ("/mnt/mydir/myfile", "r");
printf ("fopen %p\r\n", f);
if (f) fclose(f);

d = opendir ("/mnt/mydir");
printf ("opendir ret %p\r\n", f);
if (d)
{
    struct dirent *entry;
    do
    {
    errno = 0;
    entry = readdir (d);
    printf ("readdir ret %p %s, errno %d %s\r\n", entry, entry ? entry->d_name : "", errno, strerror(errno));
    } while (entry);
    closedir (d);
}

/mnt/mydir是一个 NFS 挂载(虽然我不确定这是否相关)。在该目录中打开文件的fopen()调用始终成功,并且该opendir()目录上的 也始终成功。但是,有时(大多数)readdir()失败与errno=EFAULT.

我不相信应用程序中的其他任何地方都在使用该目录做任何事情。测试与编写的完全相同,所有变量都是本地堆栈范围。

如果我将它作为独立程序运行,它总是会成功。

任何人都可以就这里可能导致 EFAULT 的原因提供任何建议吗?我很确定我的 DIR 指针变量没有被破坏,尽管我猜 DIR 结构本身可能是。我没有在其他地方看到任何堆损坏的证据。

4

2 回答 2

0

man 2 readdir页面:

       EFAULT Argument points outside the calling process's address space.

这意味着您的结构已损坏

于 2013-02-14T10:31:44.700 回答
0

我想我找到了问题所在。opendir/readdir 的 uClibc 实现对目录执行 stat(),然后执行大小为 statbuf.st_blksize 的堆栈 alloca()。我的 NFS 目录以 rsize=512KB 挂载,导致 readdir() 尝试在堆栈上分配 512KB 来保存凹痕。我的嵌入式设置在堆栈之间没有那么大的空间,所以在某些时候会在内存中碰到下面的东西并导致 EFAULT。

如果我将 NFS 挂载选项更改为 rsize=4096,它可以正常工作。

于 2013-02-28T11:43:31.190 回答