QExtSerialPort Race Condition Found

We found a subtle bug in the latest version of QExtSerialPort (the December 9th, 2012 revision 1349938a5827 version) that could cause memory corruption and an unexpected crash. This bug is subtle because it is seldom triggered. You’ll get it once in a long while if you run a separate thread that continually writes to the serial port. It will eventually trigger a (d->ref == 1) assertion in QList.cpp because of trying to reallocate memory while it is being used elsewhere. One method to find this error immediately is to enable Windows heap and exception handling using Microsoft’s Application Verifier. If you add your application to Application Verifier’s list and then run your application in a debugger, you’ll get an immediate exception in QExtSerialPort.

Here are the details of the problem:

In the writeData_sys method, data that is not written immediately, is added to a QList of pending overlapped writes called pendingWrites. Since QLists are not thread-safe, this is protected by a QWriteLocker.

Later, when the data has been written, the _q_onWinEvent method is triggered to erase the written overlapped write objects from the pendingWrites QList. This seems to be protected by a QWriteLocker as well. However, since QList is not thread-safe, even iterating through the QList has to be protected by this QWriteLocker. The reason is that if you have a thread that’s writing data, it’s appending to the pendingWrites QList which can cause the underlying memory in this QList object to get reallocated if there isn’t sufficient room for the additional item.

So the revised code from _q_onWinEvent should be:

We’ve submitted a bug report to the project that hopefully gets addressed.

2 thoughts on “QExtSerialPort Race Condition Found

Leave a Reply