[solved] QSerialPortInfo::availablePorts() crashing on osx
-
Hey guys,
I've been using QtSerial in Qt 5.1 and it seems to work fine in linux and windows but when I compiled and try it on OSX I get a malloc: *** error for object 0x1040b0000: pointer being freed was not allocated.
It seems like it works about 1/2 the time and crashes the other 1/2.
My app calls refresh() to refresh a view with serial devices in it when it launches and then again if the user triggers the refresh action via menu or hotkey.
Here is a backtrace on the crash:
App(5684,0x7fff719fa180) malloc: *** error for object 0x1040b0000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debugProgram received signal SIGABRT, Aborted.
0x00007fff893a1212 in __pthread_kill ()
(gdb) bt
#0 0x00007fff893a1212 in __pthread_kill ()
#1 0x00007fff8940ab54 in pthread_kill ()
#2 0x00007fff8944edce in abort ()
#3 0x00007fff894229b9 in free ()
#4 0x00000001019a4c77 in QSerialPortInfo::availablePorts ()
#5 0x000000010001503f in TerminalManager::refresh (this=0x108180120) at terminalmanager.cpp:68
#6 0x0000000100020e10 in TerminalManager::qt_static_metacall (_o=0x108180120, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0x7fff5fbfee90) at moc_terminalmanager.cpp:85
#7 0x0000000100b56931 in QMetaObject::activate ()
#8 0x0000000100e98572 in QAction::activate ()
#9 0x0000000100e965fe in QAction::qt_static_metacall ()
#10 0x0000000100b56931 in QMetaObject::activate ()
#11 0x0000000105a40273 in -[QCocoaMenuDelegate itemFired:] ()
#12 0x00007fff834db959 in -[NSApplication sendAction:to:from:] ()
#13 0x00007fff8361136c in -[NSMenuItem _corePerformAction] ()
#14 0x00007fff8361105a in -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] ()
#15 0x00007fff8360fce0 in -[NSMenu performKeyEquivalent:] ()
#16 0x00007fff8360f1a3 in -[NSApplication _handleKeyEquivalent:] ()
#17 0x00007fff834cc143 in -[NSApplication sendEvent:] ()
#18 0x0000000105a3fa80 in -[QNSApplication sendEvent:] ()
#19 0x00007fff833e221a in -[NSApplication run] ()
#20 0x0000000105a3d47d in QCocoaEventDispatcher::processEvents ()
#21 0x0000000100b264dd in QEventLoop::exec ()
#22 0x0000000100b2a049 in QCoreApplication::exec ()
#23 0x0000000100006ad9 in main (argc=1, argv=0x7fff5fbffb28) at main.cpp:49Sometimes the app crashes right when it's starting, other times it gets loaded and the view "refreshes" properly. But if I hit refresh it will almost always crash with that free issue.
Since the pointer being freed is inside the QtSerial component I don't think there is much I can do but thought I'd ask to see if anyone had encountered this.
I couldn't find a bug posted about this issue either.
Any ideas?
-
Hi,
Could you post a minimal code sample that can reproduce the problem ?
-
A friend of mine found the problem in the Qt code, here was his email to me:
In this case the problem it appears to be a flaw in the I/O Kit logic inside of the Qt source code. As you can see from the lines of code below the Qt source code is assigning entry to equal service and later on it is freeing both of these variables independently. Once entry is freed the value of service is already deallocated so the code is attempting to free the same value twice.
Line 98: io_registry_entry_t entry = service;
Line 195: (void) ::IOObjectRelease(entry);
Line 264: (void) ::IOObjectRelease(service);
I am rebuilding with his patched file and will post back in this thread if it works or not.
Also as for a code sample that would work, it is pretty simple to test:
@
#include <QSerialPortInfo>int main(int, char**)
{
QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
return 0;
}
@That should crash on a mac if the circumstances described in the above logic path happen. For me it's about every other time I launch this app.
-
Nice catch !
Did he consider submitting a patch ?
-
One of us will once we get it working. Unfortunately I'm still having the issue with the patched code, so I'm thinking some other memory issue in that code was missed.
It seems to happen less now, but I can still make it happen after about 5 or so calls to availablePorts().
Gonna look into it some more, and will post back.
I've never had to post a bug or patch to Qt, is there an easy way to do it?
-
Sure there is:
The "bug report system":http://bugreports.qt-project.org/issues is there for reporting.
And here for "patch submission":http://qt-project.org/wiki/Gerrit_Introduction
-
Thanks for the links.
Turns out this may not be a Qt problem. I added a bunch of qDebugs() to try to find where the problem was and it was dying in a weird part which made me suspicious.
So I simplified the code to just a console app that repeatedly called availablePorts() and it isn't crashing.
This makes me think it was something in one of the other threads of the app. Weird that it only happens during an availablePorts() call but such is the nature of threading issues.
So back to the investigation step to try to narrow this down. At this point I'm pretty confident it isn't a Qt issue.
I'm guessing that double free that my friend found is actually ok with the release system in IOKit. It probably just ignores it as an invalid object. So no patch required.
-
Well after a ton of wasted time digging through my code and threads I decided to upgrade to 5.1.1 and the bug is gone.
Turns out it was something with Qt 5.1 and that they knew and resolved already.
Marking this as solved.
-
Better that than the other way around :)
Happy coding !
-
The bug is still there.
I've got the pretty same crash on qt 5.2.0 (vs2010 build). Trying to bind QtSerialPort to Qt gui application.
Updated: the same in console application.
Call stack:msvcr100d.dll!operator delete(void * pUserData) Line 52 + 0x51 bytes C++
QSerialPortInfo::`scalar deleting destructor'() + 0x21 bytes C++
QList<QSerialPortInfo>::node_destruct(QList<QSerialPortInfo>::Node * from, QList<QSerialPortInfo>::Node * to) Line 425 + 0x2f bytes C++
QList<QSerialPortInfo>::dealloc(QListData::Data * data) Line 779 C++
QList<QSerialPortInfo>::~QList<QSerialPortInfo>() Line 754 C++ -
Yea you're right, I had the problem again with Qt 5.2 on my mac.
What I believe is the problem was the ICU library. Since I had built Qt 5.2 from scratch whereas the Qt 5.1.1 I had used the pre-built version.
I updated my ICU library (also built from scratch) and rebuilt Qt 5.2 against that and the problem was finally resolved.
I can't guarantee that it was an ICU issue but the changing of ICU to 52 (was using 48) seems to have resolved the issue.
If your ICU library is self built I would try upgrading to 52 as well and rebuild your Qt. Alternately I haven't had a problem with this bug and the prebuilt Qt libraries so you can always use those until you can get your build issue worked out.
Sorry I never updated this thread with my new findings. :)
-
Thank you for your reply.
I haven't ever seen ICU library, which packages it could be provided with on my system? And what dependencies does it have with Qt? -
It is an internationalization package. Qt is dependent on it for QtWebKit. If you don't use or haven't compiled in QtWebKit you won't need it.
I don't think it is installed by default with windows, I could be wrong though I don't use windows much.
You can find more about it and download at:
It may not have been ICU changes that fixed my problem. It could have been the rebuild of the source. If you are using pre-compiled Qt or Qt Creator and you are seeing this problem I would look deeper in your code as it may not be the same thing I was experiencing. I never experienced this on windows or linux, only osx.
-
I read about icu and scan my system. There is no icu files or libs in my Qt sources. I don't use QtWebKit. There is no any evidence that basic example QtSerialPort application that doesn't use any additional Qt modules could crash because of one of QtWebKit dependencies.
I don't use pre-compiled Qt, I built Qt from sources using vs2010 command prompt and jom. -
@#include <QtSerialPort/QSerialPortInfo>
int main(int argc, char *argv[])
{
QSerialPortInfo::availablePorts();
}@
It's enough to crash. -
Ok, not webkit or icu then for sure.
Try getting the pre-built sources and compile and test with those. There has to be something during the build that is causing that crash. I thought mine was ICU as when I changed ICU versions and rebuilt it was "fixed". However in light of your issues maybe it was something else entirely but the rebuild fixed it anyway.
-
There is no crash in release. I't is only in debug build configuration.
-
My crash happened in both debug and release.
-
Would you please describe you system configuration at
https://bugreports.qt-project.org/browse/QTBUG-36559#comment-230605,
I submited there. -
I made further step. I avoided using than function and initialized serial port with nam string:
QSerialPortInfo info("COM25");
I began sending data from my device to computer and tried to catch it.
It worked in release but in debug there wasn't any data received.