Puzzling segmentation fault on FD_ISSET()

Discussion in 'C++' started by Alvin, Jan 28, 2007.

  1. Alvin

    Alvin Guest

    Note: Source code and compile commands are at the bottom.

    I've spent some time with a friend making a nice and simple to use
    OOPified C++ networking layer for TCP that works on multiple
    platforms. As I was about to conclude its functionality and simply
    testing it on win32, I ran into a strange problem (I'll cover it in a
    moment). Everything compiles cleanly (-Wall barfs lots of warnings,
    but they just complain about type casting) on all platforms, but the
    same error happens on all platforms, too. And not on just one computer
    or locally, either.

    Anyway, the error is put simply, a segmentation fault. When my example
    multiplexing server runs along side the complimentary client example,
    everything is fine until excessive connections commence. A few more
    clients don't harm it at all, but add more than 3 and - depending on
    seemingly nothing - as soon as one last client joins, it will give in,
    segfault and attempt to send a FIN to every connection (but apparently
    fails to contact all clients all the time, if ever - my observations
    weren't geared to this specific aspect). There's no specific limit,
    but it seems to never be less than 4 connections.

    To be more specific, as soon as the last client ("last straw on the
    camel's back") connects, the server will segfault. After a few tries
    on various machines, remote connections, different operating systems
    and such, it seemed that it wasn't a one-off thing or platform
    specific. I ran it through GDB:

    Program received signal SIGSEGV, Segmentation fault.
    Error while running hook_stop:
    Invalid type combination in ordering comparison.
    0x0804997c in Select::StartSelect (this=0xbfb5aa10) at dhsocks.cpp:
    433
    433 if(FD_ISSET(readsock->GetSocket(), &readfd)) {

    It puzzles me as to why it fails on the condition above. The fact that
    it doesn't generally have a set limit and is seemingly random (but
    never very high).

    Anyway, that's as far as I've investigated and I can't see anything
    even remotely useful (the debug message is rather ambiguous - as I
    said, I can't imagine why it would segfault there). By far the
    strangest error I've ever encountered.

    I'm hoping the collective knowledge of people who look here can help
    solve the problem. I've never really seen anything like this before,
    so I'm stuck. I've no idea what to Google either.

    Thanks,
    Alvin.

    (it's called dhsocks if that helps to understand anything)

    Source code:
    HTTP: http://svn.digital-haze.net/dl.php?repname=dhsocks&path=
    %2F&rev=39&isdir=1 (tarball)
    SVN: svn co -r 39 http://svn.digital-haze.net/dhsocks (will make
    dhsocks directory in working directory)

    Compile commands:
    g++ ./dhsocks.cpp ./selectserv.cpp -o ./selectserv -ggdb
    g++ ./dhsocks.cpp ./selectclient.cpp -o ./selectclient -ggdb
    Alvin, Jan 28, 2007
    #1
    1. Advertising

  2. Alvin schrieb:
    > I've spent some time with a friend making a nice and simple to use
    > OOPified C++ networking layer for TCP that works on multiple
    > platforms.

    [...]

    A very good example of very bad C++. Sorry.

    Some points:

    (Source code is here:
    http://svn.digital-haze.net/dl.php?repname=dhsocks&path=
    %2F&rev=39&isdir=1 (tarball))

    1) int Socket::Send(char *str, int length)
    {
    [...]
    char sendstr[length];

    Lengths of arrays must be compile time constants in C++. This doesn't
    compile unless you use a gcc extension.

    2) In main():

    temp->Send(asdf, sizeof(packet));

    You try to send sizeof(packet) data but you don't know how big the buffer
    asdf pointing to is.

    3) You leak memory. Socket::Recv retuns a buffer new'ed in the function
    that never gets released.

    4) You mix value semantics and reference semantics (pointers):

    Socket Socket::Accept();
    Socket* Select::StartSelect();

    5) No exception safety. The are no destructors that close sockets. Google
    for "RAII".

    > Program received signal SIGSEGV, Segmentation fault.
    > Error while running hook_stop:
    > Invalid type combination in ordering comparison.
    > 0x0804997c in Select::StartSelect (this=0xbfb5aa10) at dhsocks.cpp:
    > 433
    > 433 if(FD_ISSET(readsock->GetSocket(), &readfd)) {
    >


    I think the problem is elsewhere. But the socket functions you use are
    offtopic here. Better ask in a platform specific newsgroup, but one I found:

    <OT>
    In char *Socket::Recv():

    int size;
    int n = recv(sockfd, (char *) &size, sizeof(int), MSG_PEEK);

    recv() doesn't fill the data size in the second parameter, it puts the data
    into the size variable. So whatever data you get, you work with some
    undefined size and use it to allocate the buffer.

    You gt undefined behaviour and your program crashes.
    </OT>

    --
    Thomas
    http://www.netmeister.org/news/learn2quote.html
    Thomas J. Gritzan, Jan 28, 2007
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Hunsley
    Replies:
    17
    Views:
    865
  2. Pud
    Replies:
    0
    Views:
    574
  3. Replies:
    0
    Views:
    527
  4. Ivan Vecerina
    Replies:
    0
    Views:
    483
    Ivan Vecerina
    Jun 29, 2003
  5. Vasileios Zografos

    Re: segmentation fault exception handling

    Vasileios Zografos, Jun 30, 2003, in forum: C++
    Replies:
    5
    Views:
    15,605
    Pete Becker
    Jul 1, 2003
Loading...

Share This Page