468,268 Members | 1,549 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,268 developers. It's quick & easy.

Puzzling segmentation fault on FD_ISSET()

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[i]->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?r...=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

Jan 28 '07 #1
1 3930
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?r...=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[i]->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
Jan 28 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Fra-it | last post: by
18 posts views Thread by Digital Puer | last post: by
27 posts views Thread by Paminu | last post: by
7 posts views Thread by pycraze | last post: by
3 posts views Thread by madunix | last post: by
10 posts views Thread by Pedro Pinto | last post: by
6 posts views Thread by DanielJohnson | last post: by
reply views Thread by NPC403 | last post: by
reply views Thread by kermitthefrogpy | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.