可以使用未添加到选择集中的描述符调用FD_ISSET吗



我正在调试一个选择循环,该循环正常工作,但在重负载下会因分段故障而终止。我已经发现,程序有时会调用FD_ISSET()来获取未添加到选择集的(正确的)描述符。类似于以下片段:

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void die(const char* msg)
{
fprintf(stderr, "fatal %s", msg);
exit(1);
}
int main(void)
{
FILE* file = fopen("/tmp/test", "r");
if (file == NULL)
die("fopen");
int file_fd = fileno(file);
fd_set read_fds;
int max_fd = 0;
FD_ZERO(&read_fds);
// Only stdin is added to read_fds.
FD_SET(0, &read_fds);
if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) < 0)
die("select");
if (FD_ISSET(0, &read_fds))
printf("Can read from 0");
// !!! Here FD_ISSET is called with a valid descriptor that was 
// not added to read_fds.
if (FD_ISSET(file_fd, &read_fds))
printf("Can read from file_fd");
return 0;
}

很明显,用!!!标记的检查永远不应该返回true,但它是否可能是SEGFAULT的原因?当我在valgrind下运行这个片段时,没有报告任何错误,但当我在val下运行负载测试时,我会偶尔出现错误,比如:

==25513== Syscall param select(writefds) points to uninitialised byte(s)
==25513==    at 0x435DD2D: ___newselect_nocancel (syscall-template.S:82)

FD_ISSET()测试文件描述符是否是集合read_fds的一部分。这意味着FD_ISSET不应导致分段故障。

在调用FD_ISSET之前,请尝试检查errno值集。select应该是segfault的原因。

还要检查file_fd值是否不大于FD_MAX

相关内容

最新更新