0

私はかなり奇妙な問題に遭遇しました:

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正しく設定されています
  • またsockfdmaxfd有効な記述子です。

クロスコンパイル中であり、コンパイル先のプラットフォームでgdbを使用できないため、デバッグ情報(gdbなど)を提供できません。

4

1 に答える 1

0

気にしないで、私はそれを理解しました。*愚かな私*

結局のところ、セグメンテーション違反は疑わしい位置で実際に発生したことはなく、stdoutがフラッシュされなかったため、セグメンテーション違反の前の最後のprintfが表示されることはありませんでした。実際のセグメンテーション違反は少し遅れて発生し、(もちろん)私の間違いでした。

それにもかかわらずthx

于 2012-08-28T11:34:10.477 に答える