我正在調試一個選擇循環,通常工作正常,但在重負載下死於分段故障。我發現該程序有時會調用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,但它是可能的,它可以是段錯誤的原因是什麼?當我運行的valgrind下這個片段中,沒有錯誤的報道,但是當我在Valgrind的運行我的負載測試我像ocasionnaly seing錯誤:
==25513== Syscall param select(writefds) points to uninitialised byte(s)
==25513== at 0x435DD2D: ___newselect_nocancel (syscall-template.S:82)
此代碼不應該SEGFAULT無論'file_fd'是無效的,或者您不在問題發佈的代碼。 – iabdalkader