QNetworkInterface::allAddresses() freez
-
Hi there,
i am running an application in which i constantly checking every 5 secs which network interfaces are available. Therefore i use a QTimer to call a function in which i search for available interfaces with QNetworkInterface::allAddresses(). I use this to know on which ip addresses i am available for clients to connect to. This works quite well for an hour or so. But suddenly this call to QNetworkInterface::allAddresses() seems to never return and freez the thread its called from. My other network Thread is getting constantly requests which emits signals ... but they never arrived on the thread allAddresses() is called from. If i qDebug() some messages before and after allAddresses() i can see them until the program freezes and the after qDebug() message is not showing up. At this time the application is on sleep state in the process manager in Gnome. If i call a kill -SIGCONT to the application and running it in the debugger the debugger stays on allAddresses() every time and i can not step over this call.
What could be possible reasons that allAddresses() never return? I haven't gone through the qt code yet but are there any loocks etc. i could run into? Broken networkinterface drivers? how could i track this down? I am running this on an archlinux 4.0.1 with qt 5.4.1 and gcc 4.9.2 on an iMac retina and i7 mac mini with the same symptoms.
could there somehow be a deadlock created by me with the QTimer ( i am not aware on which thread the signal - my function - is running that is called from the QTimer) if there is network going on ( i have a signal from a socket to handle UPD messages on that object and sending http requests from this object which is my "network manager" object)
-
.
void Communicator::init() { QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(onCheckSetLocalIpAdress())); timer->start(5000); } void Communicator::onCheckSetLocalIpAdress() { qDebug() << "on check set local ip adress"; this->checkSetLocalIpAdress(); } void Communicator::checkSetLocalIpAdress() { QRegExp re_ip("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b"); QRegExp re_usb_ip("\\b192.168.42.\\d{1,3}\\b"); QString oldIP = localIP; qDebug() << "before loop"; for(QHostAddress interface : QNetworkInterface::allAddresses()) { QString tempIp = interface.toString(); qDebug() << "ip: " << tempIp; if(tempIp.contains(re_ip)){ qDebug() << "c: " << tempIp.compare("127.0.0.1"); if(tempIp.compare("127.0.0.1") != 0){ localIP = tempIp; } if(tempIp.contains(re_usb_ip)) { localIP = tempIp; break; } } } qDebug() << "oldip: " << oldIP << " newip: " << localIP << " c: " << oldIP.compare(localIP);
}
-
Hi,
Did you try to benchmark checkSetLocalIpAdress ? If it takes more that 5 seconds then you might be stacking up calls to it.
In any case, wouldn't something like zeroconf (a.k.a bonjour) be something suited to your needs ?
-
@pythoneer85 said:
could there somehow be a deadlock created by me with the QTimer ( i am not aware on which thread the signal - my function - is running that is called from the QTimer) if there is network going on ( i have a signal from a socket to handle UPD messages on that object and sending http requests from this object which is my "network manager" object)
You can also use some tool (for instance http://valgrind.org/) to detect deadlocks
-
@SGaist said:
Did you try to benchmark checkSetLocalIpAdress ? If it takes more that 5 seconds then you might be stacking up calls to it.
Good Idea. I'll try that tomorrow. But just from looking at the terminal output as it dies its looking ok until it just simply stops printing.
In any case, wouldn't something like zeroconf (a.k.a bonjour) be something suited to your needs ?
Didn't really look into that but as you can see there is a (simplified) version of behavior going on which depends on what kind of ip addresses the application sees on the interfaces, which are changing all the time. I did not evaluate if this is applicable with zeroconf. anyway we need a working version for Monday and i think its unrealistic to begin something new with e.g. zeroconf.
@mcosta said:
You can also use some tool (for instance http://valgrind.org/) to detect deadlocks
Oh yes, thanks ... sometime one is so "in the zone" .. i'll try to throw valgrind at the application tomorrow.
Whats a bit weird is, that it seems to only crash on the boxes with Linux 4.0.1 Kernel. I have one on my dev machine (simple Arch PC) and on the deployment Targets (iMac & macMini) (Antergos). On this machines its hanging at the exact same position in code (sadly not really reproducible, sometimes 20 minutes, sometimes 2-3 hours) On the same machines (except my dev one) running Ubuntu 14.10 – dont recall the Kernel Version – its running for quite some hours and i let it run over night to see if its working. On some other machines (older iMac macMini and a PC) its seems to be the same with Ubuntu 14.10.
I somehow guess it has something to do with the Kernel :( ... if it where only crashing on the Apple Machines with broadcom chips i could "understand" that. But regardless of using the opensource b43 or the prpt. driver the behavior is the same even on my dev machine which i thought is running quite well. But after some time, the same thing, allAddresses() never return ...
-
Just a status update for anybody interested and for documentation.
The machines running Ubuntu 14.10 Kernel 3.16 still running since yesterday. Machines with Kernel 4.0.1 crashed after eg. 2 hours. I now downgraded to a lts version of the Kernel 3.14 on those machines crashing.In two weeks, when this project is over, i'll try to extract and provide a minimal version of this and try to investigate this further. for now i only try to find a system configuration that just simply work :( i'll update this post accordingly.