Segmentation fault or overflow when streaming from a QSerialPort
-
- Don't use threads, you doing it wrong (check your thread's identifiers, check on warning messages from console)
- qextserialport is not qtserialport, and it works differently
-
thanks for your reply
@Todd-Morehouse
I don't have any connection/communication problems. It's just he's having an overflow after a few seconds and crashes then. I.e.: everything works as expected until the segfault@kuzulis
obviously something is wrong, but that didn't help to identify the errorEdit: I only receive this when in streaming mode (when endless messages arrive at the serialport), it works like charm when polling - the naive approach would be clearing the input/output buffer but that didn't solve it
Edit2: I have absolutly no problem whether in streaming nor polling when I'm using the exact same implementation for wireless communication (QTcpServer/QTcpSocket) - so I guess the error must be on QSerialPort's side, as the thread runs harmlessly with the wireless connection
-
Update: it turns out when increasing the pirority and stacksize it doesn't crash anymore (at least for the observed time). However I'm not content with this solution as if there was a memory leak it actually still should be persistent, just at a later point now.
wiredThread->setPriority(QThread::TimeCriticalPriority); wiredThread->setStackSize(10000000);
-
This post is deleted!
-
@QtExchange said in Segmentation fault or overflow when streaming from a QSerialPort:
wiredThread->setPriority(QThread::TimeCriticalPriority);
wiredThread->setStackSize(10000000);This really doesn't mean much. On Linux you don't even have thread priorities. My suggestion is to clean up your code - remove the unnecessary mutexes, the clears and such, and just use the serial port as it was intended. For example:
void WiredDev::receiveMessage() { // The port has already signaled it's ready to be read receivedMessage.append(readAll()); }
I have a project deployed with
QSerialPort
(a daemon) that's been running thousands of hours without issue, so you should search the problem in your code. Additionally, @kuzulis is correct - there's no gain here in threading the serial port. -
Update:
I believe the error is because of a simultaneously memory access (on
receivedMessage
), between the "receiving part" of theQSerialPort
and the "processing part" of my library.Since I'm using additionaly mutexs for variables/containers that are used on both sides (which actually never should interfere) the error didn't occur anymore. However since I implemented the
QMutex
es my program became very slow (like 1-2 s between an update), so i have to look how to accelerate that part.So either the problem is solved because of the mutexes, or the problem is just suspended because of the lower processing speed. I'm investigating
-
@QtExchange said in Segmentation fault or overflow when streaming from a QSerialPort:
Since I'm using additionaly mutexs for variables/containers that are used on both sides (which actually never should interfere) the error didn't occur anymore. However since I implemented the QMutexes my program became very slow (like 1-2 s between an update), so i have to look how to accelerate that part.
Well you shouldn't need any mutexes nor to share the data (in most of the cases), you should transfer whatever it is you want between the threads with the help of the signal-slot mechanism.
-
The QMutex should not be the problem but what you do between the lock() and unlock() commands could easily cause issues with performance as it can block other threads.
The mutex should only be used to prevent any shared data from being simultaneously read and written. In your example you lock the mutex around the Tx, Rx functions. I know the QSerialPort has buffers and all that but you are blocking while the mutex is locked and serial is very slow which is likely why you have a 1-2 s delay between updates (?).
If you are using two buffers (looks like transmitMessage and receivedMessage are likely QByteArrays used as buffers) you should have read and write functions to get or set the data in these buffers as opposed to locking all the functions that might access the data in these variables.
QByteArray Get_TX_Buffer(void) { QByteArray tx_buffer; mutex.lock(); tx_buffer = transmitMessage; mutex.unlock(); return tx_buffer; } void Set_RX_Buffer(const QByteArray &rx_buffer) { mutex.lock(); receivedMessage.append(rx_buffer); mutex.unlock(); }
You might be better off not using a QThread (?). I have done serial communications using a QThread as it was more appropriate in my case but it all depends on the situation I suppose.
-
@kshegunov
The trick is one QByteArray receives the data (on signal slot basis), where the other container (which is just a copy of the receiver-QByteArray) is parsing the received Data, as the symbols come in a random order. I could think of having an extra signal-slot that exchanges the data between both containers whenever it is demanded, but it sounds like I have to double check if I'm actually dealing with the most current data.@Rondog There's an extra mutex for the device access, and another one for the shared message container. I'm using QThread because of maintenance reasons, where multiple different device communications (Serial, TCP/IP ...) shall be as generic as possible and because I'm dealing with QElapsedTimer, that needs the thread.
Unfortunately I can't reach the code in the next week, I'll keep it updated on new events.
-
@QtExchange said in Segmentation fault or overflow when streaming from a QSerialPort:
The trick is one QByteArray receives the data (on signal slot basis)
QByteArray
can receive nothing, it's an array of bytes - a container, nothing more, nothing less.where the other container (which is just a copy of the receiver-QByteArray) is parsing the received Data, as the symbols come in a random order.
??!
How can you parse something that doesn't have any order? And where is this other container?I could think of having an extra signal-slot that exchanges the data between both containers whenever it is demanded, but it sounds like I have to double check if I'm actually dealing with the most current data.
I don't follow. Why would be this even needed ...?
There's an extra mutex for the device access, and another one for the shared message container.
Qt imposes thread affinity on
QObject
instances, you don't need a mutex for device access, and you shouldn't share the message container.and because I'm dealing with QElapsedTimer, that needs the thread.
In what universe
QElapsedTimer
needs a thread ...?! It's like saying that an integer needs a thread ... I don't get it.