PDA

View Full Version : "QSocketNotifier: invalid socket 'Write' and type 26, disabling" What generates this?



MattPhillips
26th September 2010, 16:40
Hello,

EDIT: See 1st reply for likely solution.

I've seen this question get asked a lot but haven't found much of an answer beyond 'something is wrong with your sockets'. I've found this (http://www.qtcentre.org/threads/16179-QSocketNotifier-Invalid-socket-12-and-type-Read-disabling...)--thanks caduel--which says that 26 is likely an invalid file descriptor. How would an invalid descriptor come to be sent to a QSocketNotifier method? The socket in question is a QLocalSocket (one of two write sockets), and here is the code I use to send a message:


void MyClass::WriteToLog(const string& msg, MY_MSG_TYPE type)
{
QByteArray qb;
QDataStream out(&qb,QIODevice::WriteOnly);
out << quint16(0) << quint8(type) << QString(msg.c_str());
int num_bytes = qb.size() - sizeof(quint16); //Subtract four because in reading the
//size information, the two bytes containing it are removed from the stream
// Also sizeof(MY_MSG_TYPE) == 8
out.device()->seek(0);
out << quint16(num_bytes);

my_socket->write(qb);
my_socket->flush();
}

This seems to happen more frequently the more data I send through this socket, but I don't really send that much, maybe several hundred bytes every vertical refresh (60Hz), or ~50KB/sec tops to get this.

I looked at the QSocketNotifier code and what I saw there confused me a little bit--


QSocketNotifier::QSocketNotifier(int socket, Type type, QObject *parent,
const char *name)
: QObject(parent)
{
setObjectName(QString::fromAscii(name));
if (socket < 0)
qWarning("QSocketNotifier: Invalid socket specified");
sockfd = socket;
sntype = type;
snenabled = true;

...
}

It doesn't return the complete error message, and in the message I do get, the socket descriptor is always >0, e.g. 24 or 26.

Lastly, this crash is happening in a process launched from the one I launch using QtCreator, so I don't get any debugging output beyond what's in the subject line.

Can anybody help me with this? Thank you--

Best,
Matt

MattPhillips
26th September 2010, 16:47
Hello,

So just as I was finishing that post it struck me that maybe the 'my_socket->flush();' command was the problem; according to Qt documentation it should be unnecessary. (Couldn't bring myself to just toss the post I just spent 45min composing though). I took it out, and now at least temporarily the problem seems to have disappeared. So perhaps this changes my question: Do I lose anything by taking that out? I want this information to be sent to the next process as quickly as possible, is it possible that other events will be processed before the QByteArray is sent?

Matt

MattPhillips
28th September 2010, 02:41
So this solution isn't a silver bullet after all. On Ubuntu, I'm finding that if I *don't* have a flush statement, messages aren't sent at all--even if mysocket->write(qb) is the last statement of the function. Anybody know what's up with this? The socket is a member of MyClass and is created with


mysocket = new QLocalSocket();
mysocket->connectToServer("myserver",QLocalSocket::WriteOnly);

Best,
Matt

tbscope
28th September 2010, 07:53
Do you use any threading?

MattPhillips
29th September 2010, 03:53
Hi tbscope,

Yes. The process that is receiving these messages does so in a worker thread with its own event loop. The MyClass instance getting used is owned by the main thread, and WriteToLog is a slot. I call it directly (i.e. myclassinstance.WriteToLog(...)) from elsewhere in the main thread, and via a signal from a worker thread (that is also used for interprocess communication, but reads rather than writes). I'm using the default Qt::ConnectionType there.

Best,
Matt

tbscope
29th September 2010, 05:41
Are these Qt threads? (as in QThread)

MattPhillips
30th September 2010, 02:02
That's frustrating, I posted a response to your comment 12 hours ago but it didn't show up in the thread. Anyway, yes these are Qt threads; and I have moveToThread(this) in the constructors and (of course) exec() at the end of the run() method.

EDIT: Sometimes, though not always, I get error messages sent to cerr (which is sent to the main process before the auxiliary process crashes). Here are two examples, first the error messages (PEVS is the name of the process that crashes):


cerr: *** glibc detected *** /home/matt/Projects/PEECS/build/../PEVS/build/PEVS: malloc(): smallbin double linked list corrupted: 0x0891d948 ***

cerr: *** glibc detected *** /home/matt/Projects/PEECS/build/../PEVS/build/PEVS: malloc(): smallbin double linked list corrupted: 0x082cb8c8 ***

And now error messages + partial backtrace:

1)

cerr: *** glibc detected *** /home/matt/Projects/PEECS/build/../PEVS/build/PEVS: malloc(): smallbin double linked list corrupted: 0x082cb8c8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x1352591]
/lib/tls/i686/cmov/libc.so.6(+0x6e710)[0x1355710]
/lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x5c)[0x1356f9c]
/usr/lib/libstdc++.so.6(_Znwj+0x27)[0x1269c07]
/home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN9QMetaType9constructEiPKv+0x260)[0xfa4e20]
/home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(+0x196b72)[0xfacb72]
/home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN11QMetaObject8activateEP7QObject PKS_iPPv+0x14c)[0xfaf47c]
/home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x80811c7]
/home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x807a2d3]
/home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x80813b3]
/home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN11QMetaObject8metacallEP7QObject NS_4CallEiPPv+0x5b)[0xf9f16b]
/home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN11QMetaObject8activateEP7QObject
[...]

2)

cerr: *** glibc detected *** /home/matt/Projects/PEECS/build/../PEVS/build/PEVS: malloc(): smallbin double linked list corrupted: 0x0891d948 ***
20:48:33.026: PEVS cerr: ======= Backtrace: =========
20:48:33.028: PEVS cerr: /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x1352591]
20:48:33.028: PEVS cerr: /lib/tls/i686/cmov/libc.so.6(+0x6e710)[0x1355710]
20:48:33.030: PEVS cerr: /lib/tls/i686/cmov/libc.so.6(__libc_malloc+0x5c)[0x1356f9c]
20:48:33.031: PEVS cerr: /usr/lib/libstdc++.so.6(_Znwj+0x27)[0x1269c07]
20:48:33.031: PEVS cerr: /usr/lib/libstdc++.so.6(_ZNSs4_Rep9_S_createEjjRKSaIcE+0x66 )[0x1243d06]
20:48:33.032: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x8072c7b]
20:48:33.032: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x80557ef]
20:48:33.032: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x8055a38]
20:48:33.033: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x8076928]
20:48:33.033: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x80544d2]
20:48:33.034: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x8080f63]
20:48:33.045: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN11QMetaObject8metacallEP7QObject NS_4CallEiPPv+0x5b)[0xf9f16b]
20:48:33.046: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN14QMetaCallEvent13placeMetaCallE P7QObject+0x36)[0xfa93f6]
20:48:33.048: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN7QObject5eventEP6QEvent+0x198)[0xfaab68]
20:48:33.049: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtGui.so.4(_ZN7QWidget5eventEP6QEvent+0x85)[0x3baec5]
20:48:33.050: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtOpenGL.so.4(_ZN9QGLWidget5eventEP6QEvent+0x57 )[0x151ea7]
20:48:33.051: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtGui.so.4(_ZN19QApplicationPrivate13notify_hel perEP7QObjectP6QEvent+0xbf)[0x35a4ff]
20:48:33.052: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtGui.so.4(_ZN12QApplication6notifyEP7QObjectP6 QEvent+0x1ee)[0x35e10e]
20:48:33.053: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN16QCoreApplication14notifyIntern alEP7QObjectP6QEvent+0x7b)[0xf98b2b]
20:48:33.053: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN23QCoreApplicationPrivate16sendP ostedEventsEP7QObjectiP11QThreadData+0x1d1)[0xf99b91]
20:48:33.065: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN16QCoreApplication16sendPostedEv entsEP7QObjecti+0x2d)[0xf99e5d]
20:48:33.066: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(+0x1b019f)[0xfc619f]
20:48:33.067: PEVS cerr: /lib/libglib-2.0.so.0(g_main_context_dispatch+0x1d5)[0x16815e5]
20:48:33.067: PEVS cerr: /lib/libglib-2.0.so.0(+0x3f2d8)[0x16852d8]
20:48:33.067: PEVS cerr: /lib/libglib-2.0.so.0(g_main_context_iteration+0x68)[0x16854b8]
20:48:33.068: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN20QEventDispatcherGlib13processE ventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE+0 x68)[0xfc64b8]
20:48:33.068: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtGui.so.4(+0x2161d5)[0x4151d5]
20:48:33.069: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN10QEventLoop13processEventsE6QFl agsINS_17ProcessEventsFlagEE+0x4d)[0xf97bfd]
20:48:33.069: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN10QEventLoop4execE6QFlagsINS_17P rocessEventsFlagEE+0xbd)[0xf97f8d]
20:48:33.070: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtCore.so.4(_ZN16QCoreApplication4execEv+0xac)[0xf99f1c]
20:48:33.070: PEVS cerr: /home/matt/qtsdk-2010.04/qt/lib/libQtGui.so.4(_ZN12QApplication4execEv+0x27)[0x359c97]
20:48:33.071: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x804f45c]
20:48:33.071: PEVS cerr: /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x12fdbd6]
20:48:33.075: PEVS cerr: /home/matt/Projects/PEECS/build/../PEVS/build/PEVS[0x804f2c1]

Just in case the problem was allocating memory for the QByteArrays I use to write to the socket, I added reserve(1024) statements to every method that used the socket. Not surprisingly, this made no difference.

Best,
Matt

MattPhillips
10th October 2010, 01:55
Anyone have an idea?

tbscope
10th October 2010, 07:32
You have a pointer where you write beyond the boundaries of the pointer corrupting the heap.

MattPhillips
13th October 2010, 15:09
Thanks tbscope. I've found that while I can't get rid of this error entirely, reducing traffic on that socket and putting the body of WriteToLog within a mutex allows me to avoid it, which is good enough for me for now. I don't understand how the problem could continue to exist once I've invoked a mutex (and WriteToLog is the only place where the socket is written to), but oh well...