我遇到了一个相当奇怪的问题:
我使用select()
来确定套接字是否可读。但是,每当客户端连接时,当我调用FD_ISSET()
来检查fd_set
中是否存在给定套接字时,我会收到段错误。
/* [...] */
while( /* condition */ ){
timeout.tv_sec = 0;
timeout.tv_usec = SELECT_TIMEOUT;
//this simply fills sockets with some file descriptors (passed in by clients - both parameters are passed by reference)
maxfd = this->build_fd_set( clients, sockets );
//wait until something relevant happens
readableCount = select( maxfd + 1, &sockets, (fd_set*)NULL, (fd_set*)NULL, &timeout );
if( readableCount > 0 ){
//Some sockets have become readable
printf( "\nreadable: %d, sockfd: %d, maxfd: %d\n",
readableCount, this->sockfd, maxfd );
//Check if listening socket has pending connections
// SEGFAULT OCCURS HERE
if( FD_ISSET( this->sockfd, &sockets ) ) {
DBG printf( "new connection incoming" );
this->handle_new_connection( clients );
/* [...] */
}else {
// Data is pending on some socket
/* [...] */
}
}else if( readableCount < 0 ) {
//An error occured
/* [...] */
return;
}else {
// select has timed out
/* [...] */
}
}
修改 是的,对于稀疏信息感到抱歉:我已经更新了代码。
this->sock_fd
设置为侦听套接字的描述符,使用this->sockfd = socket( AF_UNIX, SOCK_STREAM, 0 );
创建,然后通过listen( this->sockfd, ACCEPT_BACKLOG )
进行侦听。
build_fd_set:
int SvcServer::build_fd_set( const vector<int>& clients, fd_set& sockets ) {
//build up the socket set
FD_ZERO( &sockets );
FD_SET( this->sockfd, &sockets ); //listening socket is always part of the set
int maxfd = this->sockfd;
//Add all currently connected sockets to the list
for( vector<int>::const_iterator it = clients.begin() ; it != clients.end() ; ++it ) {
FD_SET( *it, &sockets );
maxfd = max( maxfd, *it );
}
return maxfd;
}
clients
是什么并不重要,它只是空的并且意味着在客户端连接时填充,这是因为整个事件在第一个传入连接上发生了段错误。
另外,这里有一些示例输出:
readable: 1, sockfd: 3, maxfd: 3
Segmentation fault
我可以在这里得到的东西是:
select()
的调用正常,readable
设置正确sockfd
和maxfd
也是有效的描述符。我恐怕无法向您提供任何调试信息(例如gdb),因为我正在交叉编译并且gdb在我正在编译的平台上不可用。
答案 0 :(得分:0)
没关系,我明白了。 * 愚蠢我 *
事实证明,段错误实际上从未发生在可疑位置,在segfault之前的最后一个printf从未显示,因为它没有刷新stdout。实际的段错误发生了一段时间,当然是我的错误。
尽管如此,