Problem catching exception

Hi everyone, i have the following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

string server::recibirBuffer()
{
    string rtn;
    char buffer[MAX_BUFFER+1];
    DWORD bytes;
    fd_set ss;
    timeval touts;

    FD_ZERO(&ss);
    FD_SET(cnn,&ss);

    touts.tv_sec = 5;
    touts.tv_usec = 0;

    if(select(0,&ss,NULL,NULL,&touts) == SOCKET_ERROR || (bytes=recv(cnn,buffer,MAX_BUFFER,0))<=0)
        throw 1;
    if(bytes>0)
    {
        buffer[bytes]='\0';
        rtn = buffer;
    }
    return rtn;
}


And the try catch...

1
2
3
4
5
        try{
        buffer=servidor->recibirBuffer();
        }catch(...){
        break;
        }


The problem is, sometimes my app crashes and sometimes it works perfectly. I debuged the app and it always throw the exception but sometimes it doesn't catch it.

If i replace throw 1; with exit(1); it works perfect.

PS: Sorry for my bad english.
For the exception case the stack has to be unwound between the point the exception was thrown and where it was caught. This can cause problems, e.g. half constructed objects being destructed and other stuff.

exit() just terminates the program without doing this stack unwinding.
I'm only using automatic variables on both sides.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void recibirDatosSocket(server * servidor)
{
    string buffer;
    while(1)
    {
        try{
            buffer=servidor->recibirBuffer();
        }catch(...){
            break;
        }
        servidor->sendBuffer(buffer); // echo
        cout << "Datos recibidos desde el socket: " << buffer << endl;
        if(split(buffer,"/")[0]=="salir")
            break;
    }
    TerminateThread(hComThread,0);
    terminar();
}
If you replace throw with return do you still get the error?
No, i don't get the error. It works perfectly.

1
2
    if(select(0,&ss,NULL,NULL,&touts) == SOCKET_ERROR || (bytes=recv(cnn,buffer,MAX_BUFFER,0))<=0)
        return "";


1
2
        if((buffer = servidor->recibirBuffer()) == "")
            break;
Well, the return will also unwind the stack back to the calling position so maybe its not that.

I've always derived my exceptions from the exception class, maybe try that?
Yes, i've already try that.
Your code seems fine to me. I even tested it in a small mock project and all worked as expected.

can you short circuit your code such that you test the exception in isolation - leave out the socket stuff.


are these blocking or non blocking sockets?

also when you run your app in release/non debug mode, are you sure that your client socket (the one connecting to the server) is not closing?

is application single or multi-threaded?
I'm using blocking sockets and it's a multi-threaded app. Without the socket stuff it works fine!

EDIT: The client "chats" with the server and it works perfect the problem is when i disconnect the client from the server.
Last edited on
I debuged the app and it always throw the exception
Than can't be good...
Exceptions shouldn't be part of the normal flow.

but sometimes it doesn't catch it.
Dunno why that could happend. ¿Are you sure that that is what is happenning?
I was debuggin and it said "Segmentation Fault" and prompted a Call Stack Window:

http://imageshack.us/f/825/callstack.png/
Well, SegFault is not a c++ exception.
You may have corrupted the memory earlier.


man wrote:
1
2
3
int select(int nfds, fd_set *restrict readfds,
              fd_set *restrict writefds, fd_set *restrict errorfds,
              struct timeval *restrict timeout);


The nfds argument specifies the range of descriptors to be tested. The first nfds descriptors shall be checked in each set; that is, the descriptors from zero through nfds-1 in the descriptor sets shall be examined.
¿what if nfds=0? (as you are doing)
MSDN wrote:
nfds [in]
Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx

I removed select() from my code and just used recv(). Still crashing the app.

EDIT:

My code looks like this now:

1
2
3
4
5
6
7
8
9
10
11
12
string server::recibirBuffer()
{
    string rtn;
    char buffer[MAX_BUFFER+1];
    DWORD bytes;

    bytes=recv(cnn,buffer,MAX_BUFFER,0);
    if(bytes<=0)
        throw 1;
    buffer[bytes]='\0';
    return rtn=buffer;
}


It was working fine but now still crashing.
Last edited on
¿Could you provide a minimal example?
I don't think that the crash is caused by recibirBuffer(), but you triggered undefined behaviour somewhere (by instance, in split() )
Ok so my app is like a bridge between a client app (Written in Actionscript) and a XBee. The problem is when i'm testing with the client it recieves and sends data perfectly but if the client disconnect and my app throw the exception my app crashes. I removed the exception part and it looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
string server::recibirBuffer()
{
    string rtn;
    char buffer[MAX_BUFFER+1];
    DWORD bytes;
    fd_set readmask;

    FD_ZERO(&readmask);
    FD_SET(cnn,&readmask);

    if(select(0,&readmask,NULL,NULL,NULL) == 1)
    {
        unsigned long pending;
        ioctlsocket(cnn,FIONREAD,&pending); /* Numero de bytes pendientes en el buffer de entrada */
        if(!pending || (bytes=recv(cnn,buffer,MAX_BUFFER,0))<=0)
            return rtn;
        buffer[bytes]='\0';
        return rtn=buffer;
    }
    return rtn;
}


And the thread where i recieve the data:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void recibirDatosSocket(server * servidor)
{
    string buffer;
    while(1)
    {
        if((buffer=servidor->recibirBuffer()).empty())
            break;
        servidor->sendBuffer(buffer); // echo
        cout << buffer << endl;
        if(split(buffer,"/")[0]=="salir")
            break;
    }
    TerminateThread(hComThread,0);
    terminar();
}


split function:
1
2
3
4
5
6
7
8
vector<string> split(string str, const string separator)
{
    vector<string> rtn;
    unsigned int found;
    for(str+=separator;(found=str.find(separator))!=string::npos;str=str.substr(found+separator.size(),str.size()-found))
        rtn.push_back(str.substr(0,found));
     return rtn;
}


Without the exception part it works PERFECT.
PS: I'm using blocking sockets. I've trying replacing the return rtn; with throw 1; and it crashes.
Topic archived. No new replies allowed.