PDA

View Full Version : Segfault



Dumbledore
10th November 2007, 02:40
You can only debug what you know is wrong. In this case, with my cursory knowledge of Qt, I know this code should work. (Well I know it doesn't but I don't know why.)

Problem description: I can start multiple apps and they can connect to one another, but as soon as a connection is terminated all of the apps segfault.

The problem is most assuredly within here:


void MSocketThread::run() {
MSocket mSocket;
if ( 0 != socketDescriptor ) {
if ( !mSocket.setSocketDescriptor(socketDescriptor) ) {
std::cerr << "Failed to set SocketDescriptor." << endl;
}
/* Output who joined the server */
QHostAddress ipaddress = mSocket.peerAddress();
QString ipString(tr("<font color=blue>%1 has joined.</font>").arg(ipaddress.toString()));
emit relayIncomingText(ipString);
}
connect(&mSocket, SIGNAL(connected()),
this, SIGNAL(connectionEstablished()));
connect(&mSocket, SIGNAL(inboundText(QString)),
this, SIGNAL(relayIncomingText(QString)));
connect(this, SIGNAL(sigSend(QString)),
&mSocket, SLOT(send(QString)));
connect(&mSocket, SIGNAL(error()),
this, SIGNAL(quit()));
connect(&mSocket, SIGNAL(disconnected()), this, SLOT(quit()));

if ( 0 == socketDescriptor ) {
mSocket.connectToHost(ip, port);
}


exec(); //Begin event loop.
}

jpn
10th November 2007, 08:16
Problem description: I can start multiple apps and they can connect to one another, but as soon as a connection is terminated all of the apps segfault.
There could be lots of reasons. Run the application via debugger, make it crash, and see the backtrace.





connect(&mSocket, SIGNAL(connected()),
this, SIGNAL(connectionEstablished()));
connect(&mSocket, SIGNAL(inboundText(QString)),
this, SIGNAL(relayIncomingText(QString)));
connect(this, SIGNAL(sigSend(QString)),
&mSocket, SLOT(send(QString)));
connect(&mSocket, SIGNAL(error()),
this, SIGNAL(quit()));
connect(&mSocket, SIGNAL(disconnected()), this, SLOT(quit()));

Be extremely careful with such connections. "mSocket" lives in different thread than "this", which causes all the connections to be queued, which means that the slots get also called in different thread than MSocketThread::run(). They get called in thread where MSocketThread, the receiver, lives in. This can be avoided by explicitly passing Qt::DirectConnection where needed.

Dumbledore
10th November 2007, 17:24
I don't know what you are talking about. My understanding is QThread::run is its own thread, and whatever I do within that thread is part of that thread... (Creating MSocket on the stack would mean that it runs within that thread.)

Is there half decent documentation out there on this? I can't make sense of the QT4 documentation on threads and the book GUI programming with QT doesn't do justice to threading.

One negative I have noticed about QT is there's a lack of code examples.

jpn
12th November 2007, 07:31
I don't know what you are talking about. My understanding is QThread::run is its own thread, and whatever I do within that thread is part of that thread... (Creating MSocket on the stack would mean that it runs within that thread.)

Is there half decent documentation out there on this? I can't make sense of the QT4 documentation on threads and the book GUI programming with QT doesn't do justice to threading.
Yes, but since the QThread object itself lives in another thread than the MSocket instance, signal slot connections between them get queued by default and therefore corresponding slots might end up being called in different thread than you expect. It all depends what your slots actually do. Check out Brad Hughes' multithreading presentation from Trolltech DevDays 2007: http://chaos.troll.no/~ahanssen/devdays2007/DevDays2007-Threading.pdf, starting from page 33. Also, I noticed usage of both SIGNAL(quit()) and SLOT(quit()), is this intentional?


One negative I have noticed about QT is there's a lack of code examples.
Really? http://doc.trolltech.com/latest/examples.html