0

我正在调试一个选择循环,该循环通常可以正常工作,但在重负载下会因分段错误而死。我发现程序有时会调用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 下运行此代码段时,没有报告任何错误,但是当我在 valgrind 下运行负载测试时,我偶尔会看到如下错误:

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

1 回答 1

2

FD_ISSET() 测试文件描述符是否是 set 的一部分read_fds。这意味着 FD_ISSET 不应导致分段错误。

尝试在调用 FD_ISSET 之前检查设置的 errno 值。select应该是导致段错误。

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

于 2012-12-04T15:27:29.167 回答