PDA

View Full Version : QLocalSocket issue/difference between *nix & win32



CmdrMoozy
29th July 2011, 20:07
So I'm writing an application using qt-4.7.3 that utilizes QLocalSocket/QLocalServer, and I've found some weird behavior when building my application on different OS's.

This code:


int main(int argc, char *argv[])
{
QLocalSocket s;

// Do some stuff with our socket.

QApplication app(argc, argv);
MyMainWindow w;
w.show();
}


Works as expected on Linux, but when the same code is executed on win32 it segfaults when you declare the QLocalSocket. The fix is to declare the QApplication /before/ the QLocalSocket, in which case it works fine on win32.

So basically my question is, why the different behavior, and is it possibly a bug in the QLocalSocket class? (It's also possible that I'm just doing things horribly out of order and I'm causing the issue via that. :p )

mcosta
29th July 2011, 21:07
From Qt Docs


Detailed Description
...
On Windows this is a named pipe and on Unix this is a local domain socket.
...
Note that this feature is not supported on versions of Windows earlier than Windows XP.

Probably the Windows implementation needs to access data of QApplication instance.

Remember that on Win32 Local Sockets don't exist so Qt emulate them.

CmdrMoozy
29th July 2011, 23:24
Yeah, I had read that they are implemented differently on Windows.

It just seems odd that a) it (apparently) requires QApplication, yet doesn't require it to be passed to the constructor or anything (it compiles just fine without it), and b) it segfaults in this case, instead of just producing a warning or error or something.

stampede
30th July 2011, 08:37
a) it does not have to be passed to constructor, application instance can be accessed via QApplication::instance() method
b) are you sure its not some kind of asert ?

CmdrMoozy
31st July 2011, 23:27
a) it does not have to be passed to constructor, application instance can be accessed via QApplication::instance() method
b) are you sure its not some kind of asert ?

I realize there are ways to access the QApplication instance other than having a pointer/reference to it given directly; I really just meant that if it does indeed require one to be defined, it should give some indication of that.

I am relatively certain it was not an assertion failure, but I will verify that. Does Qt even contain assertions when it is built in release mode?

stampede
1st August 2011, 07:43
Qt assertions works if QT_NO_DEBUG is not defined, but it is defined in release mode by default. So assertions will not work in release mode (as long as you leave QT_NO_DEBUG).
In debug mode, it is failed assertion:

warning: ASSERT failure in QWinEventNotifier::QWinEventNotifier(): "Cannot creat
e a win event notifier without a QEventDispatcherWin32", file kernel\qwineventno
tifier_p.cpp, line 74
Tested on this code:


#include <QLocalSocket>

int main(int argc, char *argv[]){
QLocalSocket s;
return 0;
}

But in release it crashes:


Program received signal SIGSEGV, Segmentation fault.
0x6a30dea6 in ZNK7QObject6d_funcEv () from C:\Qt\bin\QtCore4.dll
(gdb) bt
#0 0x6a30dea6 in ZNK7QObject6d_funcEv () from C:\Qt\bin\QtCore4.dll
#1 0x6a2a52bd in ZNK7QObject6threadEv () from C:\Qt\bin\QtCore4.dll
#2 0x6a2b50b4 in ZN21QEventDispatcherWin3221registerEventNotifierEP 17QWinEventN
otifier () from C:\Qt\bin\QtCore4.dll
#3 0x6a2b8d47 in ZN17QWinEventNotifierC2EPvP7QObject ()
from C:\Qt\bin\QtCore4.dll
#4 0x6ff76738 in ZN12QLocalServer21nextPendingConnectionEv ()
from C:\Qt\bin\QtNetwork4.dll
#5 0x6ff7366f in ZN12QLocalSocketC2EP7QObject ()
from C:\Qt\bin\QtNetwork4.dll
#6 0x004013db in ?? ()
#7 0x00401f2d in ?? ()
#8 0x00401be6 in ?? ()
#9 0x004010db in ?? ()
#10 0x00401158 in ?? ()
#11 0x75e81174 in KERNEL32!AcquireSRWLockExclusive ()
from C:\Windows\system32\kernel32.dll
#12 0x773ab3f5 in ntdll!RtlInsertElementGenericTableAvl ()
from C:\Windows\system32\ntdll.dll
#13 0x773ab3c8 in ntdll!RtlInsertElementGenericTableAvl ()
from C:\Windows\system32\ntdll.dll
#14 0x00000000 in ?? ()

Have you checked the Qt bug tracker (http://bugreports.qt.nokia.com/) ?
I don't know about you, but I'm always compiling and testing the debug version first, so this issue would be easily resolved thanks to the assertion. But on the other hand, creating an instance of a class should not generate segfault, surely this should be corrected.

vallidor
3rd August 2011, 08:28
i might suppose this is why: http://msdn.microsoft.com/en-us/library/ms738566(v=vs.85).aspx

before you declare your local socket, could you try calling "QHostInfo testHost = QHostInfo::fromName("google.com");" and see if it still crashes?

stampede
3rd August 2011, 10:06
before you declare your local socket, could you try calling "QHostInfo testHost = QHostInfo::fromName("google.com");" and see if it still crashes?


#include <QLocalSocket>
#include <QHostInfo>

int main(int argc, char *argv[]){
QHostInfo testHost = QHostInfo::fromName("google.com");
QLocalSocket s;
return 0;
}

In debug the same assertion fails, crash in release:


Program received signal SIGSEGV, Segmentation fault.
0x6a30dea6 in ZNK7QObject6d_funcEv () from C:\Qt\bin\QtCore4.dll
(gdb) bt
#0 0x6a30dea6 in ZNK7QObject6d_funcEv () from C:\Qt\bin\QtCore4.dll
#1 0x6a2a52bd in ZNK7QObject6threadEv () from C:\Qt\bin\QtCore4.dll
#2 0x6a2b50b4 in ZN21QEventDispatcherWin3221registerEventNotifierEP 17QWinEventN
otifier () from C:\Qt\bin\QtCore4.dll
#3 0x6a2b8d47 in ZN17QWinEventNotifierC2EPvP7QObject ()
from C:\Qt\bin\QtCore4.dll
#4 0x6ff76738 in ZN12QLocalServer21nextPendingConnectionEv ()
from C:\Qt\bin\QtNetwork4.dll
#5 0x6ff7366f in ZN12QLocalSocketC2EP7QObject ()
from C:\Qt\bin\QtNetwork4.dll
#6 0x00401415 in ?? ()
#7 0x00401f9d in ?? ()
#8 0x00401c56 in ?? ()
#9 0x004010db in ?? ()
#10 0x00401158 in ?? ()
#11 0x77621174 in KERNEL32!AcquireSRWLockExclusive ()
from C:\Windows\system32\kernel32.dll
#12 0x77b3b3f5 in ntdll!RtlInsertElementGenericTableAvl ()
from C:\Windows\system32\ntdll.dll
#13 0x77b3b3c8 in ntdll!RtlInsertElementGenericTableAvl ()
from C:\Windows\system32\ntdll.dll
#14 0x00000000 in ?? ()

But this time a warning message appears before crash and failed assertion:


warning: QObject::connect: Cannot connect (null)::destroyed() to QHostInfoLookupManager::waitForThreadPoolDone()

vallidor
3rd August 2011, 17:43
i see, and the backtrace doesn't even reference anything resembling winsock, it seems to stay within qtcore/qtnetwork. it certainly seems like a bug.

Telecaster
30th January 2012, 15:18
Hello all,

I'm building a static lib that uses QLocalSocket and when I link with a basic MSVC++ 9.0 win32 app, i'm facing the exact same issue as you (crash (in release) or Assert (in debug) telling me "Cannot Create a Win event notifier without a QEventDispatcherWin32".

Did you find any fix or workaround ?

Thanks for your help

Marc