私はかなり奇妙な問題に遭遇しました:
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など)を提供できません。