Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Repeatable crash generated by QSerialPort::waitForReadyRead
I am using Qt 5.1.1.
Has anyone else experienced a crash triggered by QSerialPort::waitForReadyRead? It always says "malloc: *** error for object 0x10587f200: pointer being freed was not allocated" and gives a stack trace like this. I have an asynchronous serial communications protocol with a hardware device which acknowledges every packet, so every time something is sent, we want to wait for a response before sending the next packet. As a result, we use QSerialPort::waitForReadyRead, but maybe that is not the best way to go about it. I will post my entire comm class if that would be helpful, I am sure it could be improved.
The crash does not occur 100% of the time, but it frequently arises early in communications, and happens on both Windows and Mac OS X.
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
*** error for object 0x10587f200: pointer being freed was not allocated
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff8c4ad866 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff954b435c pthread_kill + 92
2 libsystem_c.dylib 0x00007fff8f6a9bba abort + 125
3 libsystem_malloc.dylib 0x00007fff8cac9093 free + 411
4 QtCore 0x0000000100b2d34d QByteArray::reallocData(unsigned int, QFlagsQArrayData::AllocationOption) + 173
5 QtCore 0x0000000100b2cc85 QByteArray::resize(int) + 277
6 QtSerialPort 0x0000000101097ea9 QRingBuffer::reserve(int) + 73
7 QtSerialPort 0x0000000101096a82 QSerialPortPrivate::readNotification() + 178
8 QtSerialPort 0x00000001010966e7 QSerialPortPrivate::waitForReadyRead(int) + 151
9 QtSerialPort 0x000000010109283d QSerialPort::waitForReadyRead(int) + 13
- You can debug it yourself.
- Just do not use waitFor() methods, because they can have errors yet.
I know now from much more testing that that is the case. The issue was that I was Instantiating the QSerialPort in a class instantiated by the main thread, then using QtConcurrent::run to run the operation that would ultimately call those methods, leading to a race condition for a QByteArray once readyRead would be triggered. I realize the QSerialPort signals are not intended to be used with the signals, but this was the only way I could get it to work due to my slightly broken threading setup.
Now, I'm looking at the 'blocking master' serial port sample as it seems like my only path forward is to write my own thread as opposed to using QtConcurrent::run.
Yes, the QSerialPort class still is not thread safe, You can not use its methods from an different threads.
Thanks - using the blocking master serial port example was perfect and really not difficult at all. A simple state machine in the run loop with cond.wait(&mutex); in the default case worked on both Windows and Mac, with cond.wakeOne(); in the state machine update method. No crashes, and it does everything it needs to. Cheers!
I would advise to you to refuse from the blocking approach and use the non-blocking with signals/slots (maybe in the other thread - if need). It is preffered way, because waitForX() methods can has an errors/bugs yet
[quote author="kuzulis" date="1383833253"]because waitForX() methods can has an errors/bugs yet[/quote]Hi, have these bugs been reported? Can you please share the link to the report?
It might be "this one":https://bugreports.qt-project.org/browse/QTBUG-33987
Yes, I mean this bug. Sorry for confusion..