Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Crash on linux with selector.isReady  (Read 2632 times)

0 Members and 1 Guest are viewing this topic.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Crash on linux with selector.isReady
« on: April 27, 2014, 11:35:30 am »
Hi!

I've a crash in the function selector.isReady.

When I connect a client once it works, but, when I connect and then disconnect the client a second time, it crash.

Here's what the debugguer shows ;

#0 0x7ffff6535f79       __GI_raise(sig=sig@entry=6) (../nptl/sysdeps/unix/sysv/linux/raise.c:56)
#1 0x7ffff6539388       __GI_abort() (abort.c:89)
#2 0x7ffff65731d4       __libc_message(do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff667f415 "*** %s ***: %s terminated\n") (../sysdeps/posix/libc_fatal.c:175)
#3 0x7ffff660ab2c       __GI___fortify_fail(msg=<optimized out>, msg@entry=0x7ffff667f3ac "buffer overflow detected") (fortify_fail.c:37)
#4 0x7ffff66099f0       __GI___chk_fail() (chk_fail.c:28)
#5 0x7ffff660aa77       __fdelt_chk(d=<optimized out>) (fdelt_chk.c:25)
#6 0x7ffff7bd3d9c       sf::SocketSelector::isReady(sf::Socket&) const() (/usr/local/lib/libsfml-network.so.2:??)
#7 0x43e3c4     odfaeg::SrkServer::run(this=0x8052f0) (/home/laurent/Projets-dev/Projets-c++/ODFAEG/src/odfaeg/Network/srkserveur.cpp:79)
#8 0x7ffff6e92bf0       ??() (/usr/lib/x86_64-linux-gnu/libstdc++.so.6:??)
#9 0x7ffff62e9182       start_thread(arg=0x7ffff20fc700) (pthread_create.c:312)
#10 0x7ffff65fa30d      clone() (../sysdeps/unix/sysv/linux/x86_64/clone.S:111)
 

Is seems that there is a buffer overflow somewhere.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Crash on linux with selector.isReady
« Reply #1 on: April 27, 2014, 11:44:30 am »
When I link the sfml-network-d.so file instead of the sfml-network.so file, the problem disappear.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Crash on linux with selector.isReady
« Reply #2 on: April 28, 2014, 03:21:48 pm »
So you think that your code overflowed some buffer, try to link against the debug library and made it work (what a surprise...) and yet you still don't want to post any code for us to look at? There are some things that a callstack will not show.

I'm 99.999999999999999% sure that if you posted the code around that .isReady() call someone will notice the mistake that was made, in your code. That is of course... if you didn't already solve the problem through... other means...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Crash on linux with selector.isReady
« Reply #3 on: May 03, 2014, 09:38:19 am »
Ha, you want to see the code ???

I haven't found anything which is suspect in my source code :

void SrkServer::run () {
    running = true;
    while (running) {

        if (selector.wait(seconds(10))) {
            lock_guard<recursive_mutex> locker (rec_mutex);
            if (selector.isReady(listener)) {
                std::cout<<"client connected"<<std::endl;
                TcpSocket *client = new TcpSocket();
                if (listener.accept(*client) == Socket::Done) {
                    selector.add(*client);
                    clients.push_back(client);
                    Network::addUser(*client, udpSocket);
                }
            }
            if (selector.isReady(udpSocket)) {
                SymEncPacket packet;
                string request;
                IpAddress sender;
                short unsigned int port;
                if (udpSocket.receive(packet, sender, port) == Socket::Done) {
                    packet>>request;
                    User* user = Network::getUser(sender);
                    if (user != NULL) {
                        if (user->getRemotePortUDP() != port)
                            user->setRemotePortUDP(port);
                        Network::addRequest (user, request);
                    } else {
                        cout<<"this message don't provide from a valid client!"<<endl;
                    }
                }
            }
            vector<TcpSocket*>::iterator it;
            for (it = clients.begin(); it != clients.end(); it++) {
                TcpSocket& client = **it;
                if (selector.isReady(client)) {
                    Packet* packet;
                    bool pbKeyRsaSend = Network::hasPbKeyRsa(client.getRemoteAddress());
                    bool pbKeySend = Network::hasPbKey(client.getRemoteAddress());
                    if (pbKeySend && pbKeyRsaSend) {
                        packet = new SymEncPacket ();
                    } else if (!pbKeySend && pbKeyRsaSend) {
                        packet = new EncryptedPacket ();
                    } else {
                        packet = new Packet();
                    }
                    if (client.receive(*packet) == Socket::Done) {
                        string request;
                        (*packet)>>request;
                        User* user = Network::getUser(client.getRemoteAddress());
                        if (!pbKeyRsaSend && request == "GetPbKeyRsa") {
                            user->setUseSecuredConnexion(true);
                            Network::sendPbKeyRsa(*user);
                        } else if (!pbKeySend && request == "GetPbKey") {
                            Network::sendPbKey(*user);
                        } else if (pbKeyRsaSend && pbKeySend || !user->isUsingSecuredConnexion()) {
                            Network::addRequest (user, request);
                        }  else {
                            Network::removeUser(client.getRemoteAddress());
                            selector.remove(client);
                            delete &client;
                        }
                        delete packet;
                    } else {
                        std::cout<<"client disconnected"<<std::endl;
                        Network::removeUser(client.getRemoteAddress());
                        selector.remove(client);
                        delete &client;
                    }

                }
            }
        }
    }
}
 
« Last Edit: May 03, 2014, 09:42:30 am by Lolilolight »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Crash on linux with selector.isReady
« Reply #4 on: May 03, 2014, 10:55:27 am »
So... you add a connection to the clients vector but don't remove it when they disconnect? Good idea to dereference the socket pointer and call Selector::isReady() on it after it was deleted isn't it?

You know... reading the callstack would help:
Code: [Select]
#3 0x7ffff660ab2c   __GI___fortify_fail(msg=<optimized out>, msg@entry=0x7ffff667f3ac "buffer overflow detected")I don't know how much friendlier Linux can get when it comes to error messages...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Crash on linux with selector.isReady
« Reply #5 on: May 03, 2014, 11:16:13 am »
Argh..., right I need to also erase the client from the vector.

I've just to understand linux error messages clearly, they are not the same than windows error messages.
And I didn't still undestand them very well.